/*
 * @Author       : liubangyi liubangliuyi@163.com
 * @Date         : 2024-08-29 15:08:15
 * @LastEditors  : liubangyi liubangliuyi@163.com
 * @LastEditTime : 2025-03-17 15:40:52
 * @FilePath     : /openchaoji-corelib/evcc/gbt27930/OpenChaoJi_evcc_gbt27930_b.c
 * @Description  : evcc的GB/T 27930 B类系统主实现
 *
 * Copyright (c) 2025 OpenChaoJi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the icense for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "OpenChaoJi_evcc.h"

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)


struct OpenChaoJi_evcc_gbt27930_b_data
{
    /* -------------- IDLE 模块 特来电 -------------- */
    struct {
        int dummy;
    } idle;

    /* -------------- Trigger 模块 特来电 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tv;
    } trigger;

    /* -------------- 功能协商 模块 嘉盛 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tv;

        struct OpenChaoJi_gbt27930_b_msg_func_support_secc func_support_secc;

        struct OpenChaoJi_gbt27930_b_msg_func_support_evcc func_support_evcc;
        int func_support_secc_ok;

    } func_nego;

    /* -------------- 参数配置 模块 嘉盛 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tv;

        struct OpenChaoJi_gbt27930_b_msg_param_config_secc param_config_secc;

        struct OpenChaoJi_gbt27930_b_msg_param_config_evcc param_config_evcc;
        int param_config_secc_ok;

    } param_config;

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_AUTH == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_RFID == CONFIG_YES)
    /* -------------- 授权(RFID) 模块 鲁软 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tv;

        struct OpenChaoJi_os_soft_timer T1;

        struct OpenChaoJi_os_soft_timer T2;

        struct OpenChaoJi_gbt27930_b_msg_auth_rfid_param_secc rfid_param_secc;
        int rfid_param_secc_ok;    //充电机鉴权参数报文

        struct OpenChaoJi_gbt27930_b_msg_auth_rfid_wait_evcc  rfid_wait_evcc;

        struct OpenChaoJi_gbt27930_b_msg_auth_rfid_result_secc rfid_result_secc;
        int rfid_result_secc_ok;   //鉴权结果参数报文组

    } auth_rfid;

    #endif
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_EVIN == CONFIG_YES)
    /* -------------- 授权(EVIN) 模块 鲁软 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tv;

        struct OpenChaoJi_gbt27930_b_msg_auth_evin_req_secc evin_req_secc;
        int evin_req_secc_ok;  //鉴权请求

        struct OpenChaoJi_gbt27930_b_msg_auth_evin_param_evcc evin_param_evcc;

        struct OpenChaoJi_gbt27930_b_msg_auth_evin_result_secc evin_result_secc;
        int evin_result_secc_ok; //鉴权结果

    } auth_evin;
    #endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_RESERVE == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_RESERVE_EVCC == CONFIG_YES)

    /* -------------- 预约 模块 (暂空) -------------- */
    #endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SELFCHECK == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SELFCHECK_GENERAL == CONFIG_YES)

    /* -------------- 系统自检 模块 领充 -------------- */
     /*系统自检内容定义*/
	struct {
        struct OpenChaoJi_os_soft_timer Tv;

        int selfcheck_status_secc_ok;  //自检状态报文接收
        struct OpenChaoJi_gbt27930_b_msg_selfcheck_status_secc selfcheck_status_secc;

        int selfcheck_result_secc_ok;  //自检结果报文接收
        struct OpenChaoJi_gbt27930_b_msg_selfcheck_result_secc selfcheck_result_secc;

    } self_check;
    #endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SUPPLY == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SUPPLY_BASIC == CONFIG_YES)
    /* -------------- 供电模式 模块 (暂空) -------------- */
    #endif
#endif
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_CHARGING == CONFIG_YES)

    /* -------------- 预充及能量传输(充电) 模块 鲁软 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tv;

        struct OpenChaoJi_os_soft_timer T1;

        struct OpenChaoJi_os_soft_timer T2;

        struct OpenChaoJi_os_soft_timer T3;

        struct OpenChaoJi_os_soft_timer T4;

        struct OpenChaoJi_gbt27930_b_msg_charging_ready_secc charging_ready_secc;
        int charging_ready_secc_ok; //充电机就绪状态

        struct OpenChaoJi_gbt27930_b_msg_charging_ready_evcc charging_ready_evcc;
        bool charging_input_battery_success;//电池成功投入

        struct OpenChaoJi_gbt27930_b_msg_charging_requirement_evcc charging_requirement_evcc;

        struct OpenChaoJi_gbt27930_b_msg_charging_info_basic_evcc charging_info_basic_evcc;

        struct OpenChaoJi_gbt27930_b_msg_charging_info_battery_evcc charging_info_battery_evcc;

        struct OpenChaoJi_gbt27930_b_msg_charging_ability_secc charging_ability_secc;
        int charging_ability_secc_ok;//充电机动态输出能力
        int charging_requirement_change;

        struct OpenChaoJi_gbt27930_b_msg_charging_pause_secc charging_pause_secc;
        int charging_pause_secc_ok;//充电机暂停充电

        struct OpenChaoJi_gbt27930_b_msg_charging_pause_evcc charging_pause_evcc;

        struct OpenChaoJi_evcc_hal_samp  charging_evcc_hal_samp;

        int charging_active_charge_paused;//车辆主动暂停充电

    } charging;
    #endif
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_DISCHARGING == CONFIG_YES)
    /* -------------- 预充及能量传输(放电) 模块 暂空 -------------- */
    #endif

    /* -------------- 服务统计停止中 鲁软 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer State_Tv;

        struct OpenChaoJi_os_soft_timer Normal_Tv;
        struct OpenChaoJi_os_soft_timer Normal_T1;
        struct OpenChaoJi_os_soft_timer Normal_T2;
        struct OpenChaoJi_os_soft_timer Normal_T3;
        struct OpenChaoJi_os_soft_timer Normal_T4;
        struct OpenChaoJi_os_soft_timer Normal_T5;

        struct OpenChaoJi_os_soft_timer Fault_Tv;
        struct OpenChaoJi_os_soft_timer Fault_T1;
        struct OpenChaoJi_os_soft_timer Fault_T2;
        struct OpenChaoJi_os_soft_timer Fault_T3;
        struct OpenChaoJi_os_soft_timer Fault_T4;
        struct OpenChaoJi_os_soft_timer Fault_T5;

        struct OpenChaoJi_os_soft_timer Emrge_Tv;
        struct OpenChaoJi_os_soft_timer Emrge_T1;
        struct OpenChaoJi_os_soft_timer Emrge_T2;
        struct OpenChaoJi_os_soft_timer Emrge_T3;
        struct OpenChaoJi_os_soft_timer Emrge_T4;

        int statistics_stoping_emergency_evcc_state;//紧急停机状态 0x00 0x01 0x02 0x03 0x04
        int statistics_stoping_fault_evcc_state;//故障停机状态 0x00 0x01 0x02 0x03 0x04 0x05
        int statistics_stoping_normol_evcc_state;//正常停机状态 0x00 0x01 0x02 0x03 0x04 0x05

    } statistics_stoping;

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_STATISTICS == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_STATISTICS == CONFIG_YES)
    /* -------------- 服务统计 模块 长园 -------------- */
    struct {
        struct OpenChaoJi_os_soft_timer Tv;

        struct OpenChaoJi_gbt27930_b_msg_statistics_secc statistics_secc;
        int statistics_secc_ok;    //接收到"充电机统计信息"报文

        struct OpenChaoJi_gbt27930_b_msg_statistics_evcc statistics_evcc;

    } statistics;
    #endif
#endif

    /* -------------- END 模块 星星 -------------- */

    /* -------------- FAULT 模块 星星 -------------- */

    /* -------------- 通用数据 鲁软 -------------- */
    struct OpenChaoJi_gbt27930_b_msg_phase_info_secc phase_info_secc;
    int phase_info_secc_ok;//接收"充电机阶段信息"报文

    struct OpenChaoJi_gbt27930_b_msg_phase_ack_evcc phase_ack_evcc;

    struct  OpenChaoJi_gbt27930_b_msg_stop_info_secc stop_info_secc;
    int stop_info_secc_ok;//接收"充电机中止"报文

    struct  OpenChaoJi_gbt27930_b_msg_stop_info_evcc stop_info_evcc;
    int stop_info_evcc_sent;//0未发送 1已发送中止报文

	// 充电机直流供电回路接触器状态报文
	struct OpenChaoJi_gbt27930_b_msg_relay_status_secc relay_status_secc;
    int relay_status_secc_ok;

	struct OpenChaoJi_gbt27930_b_msg_relay_status_evcc relay_status_evcc;
    unsigned char hal_relay_status_evcc;
    struct OpenChaoJi_os_soft_timer relay_status_evcc_T1;

    // 车辆电子锁状态报文, B类系统由车端负责, 桩端无电子锁状态报文
	struct OpenChaoJi_gbt27930_b_msg_latching_status_evcc latching_status_evcc;
    unsigned char hal_latching_status_evcc;
    struct OpenChaoJi_os_soft_timer latching_status_T1;

    struct OpenChaoJi_evcc_app_start_parameter app_start_parameter;

    /* -------------- 日志专用 -------------- */
    struct {
        // struct OpenChaoJi_gbt27930_b_msg_func_support_secc func_support_secc;
        struct OpenChaoJi_gbt27930_b_msg_func_support_evcc func_support_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_param_config_secc param_config_secc;
        struct OpenChaoJi_gbt27930_b_msg_param_config_evcc param_config_evcc;
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_AUTH == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_RFID == CONFIG_YES)
        // struct OpenChaoJi_gbt27930_b_msg_auth_rfid_param_secc auth_rfid_param_secc;
        // struct OpenChaoJi_gbt27930_b_msg_auth_rfid_result_secc auth_rfid_result_secc;
        struct OpenChaoJi_gbt27930_b_msg_auth_rfid_wait_evcc auth_rfid_wait_evcc;
    #endif
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_EVIN == CONFIG_YES)
        // struct OpenChaoJi_gbt27930_b_msg_auth_evin_req_secc auth_evin_req_secc;
        struct OpenChaoJi_gbt27930_b_msg_auth_evin_param_evcc auth_evin_param_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_auth_evin_result_secc auth_evin_result_secc;
    #endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_RESERVE == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_RESERVE_EVCC == CONFIG_YES)
        // struct OpenChaoJi_gbt27930_b_msg_reserve_info_secc reserve_info_secc;
        // struct OpenChaoJi_gbt27930_b_msg_reserve_confirm_secc reserve_confirm_secc;
        struct OpenChaoJi_gbt27930_b_msg_reserve_info_evcc reserve_info_evcc;
        struct OpenChaoJi_gbt27930_b_msg_reserve_nego_evcc reserve_nego_evcc;
    #endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SELFCHECK == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SELFCHECK_GENERAL == CONFIG_YES)
        // struct OpenChaoJi_gbt27930_b_msg_selfcheck_status_secc selfcheck_status_secc;
        // struct OpenChaoJi_gbt27930_b_msg_selfcheck_result_secc selfcheck_result_secc;
    #endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SUPPLY == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SUPPLY_BASIC == CONFIG_YES)
        // struct OpenChaoJi_gbt27930_b_msg_supply_status_secc supply_status_secc;
        struct OpenChaoJi_gbt27930_b_msg_supply_status_evcc supply_status_evcc;
        struct OpenChaoJi_gbt27930_b_msg_supply_requirement_evcc supply_requirement_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_supply_ability_secc supply_ability_secc;
        struct OpenChaoJi_gbt27930_b_msg_supply_finish_evcc supply_finish_evcc;
    #endif
#endif
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_CHARGING == CONFIG_YES)
        // struct OpenChaoJi_gbt27930_b_msg_charging_ready_secc charging_ready_secc;
        struct OpenChaoJi_gbt27930_b_msg_charging_ready_evcc charging_ready_evcc;
        struct OpenChaoJi_gbt27930_b_msg_charging_requirement_evcc charging_requirement_evcc;
        struct OpenChaoJi_gbt27930_b_msg_charging_info_basic_evcc charging_info_basic_evcc;
        struct OpenChaoJi_gbt27930_b_msg_charging_info_battery_evcc charging_info_battery_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_charging_ability_secc charging_ability_secc;
        // struct OpenChaoJi_gbt27930_b_msg_charging_pause_secc charging_pause_secc;
        struct OpenChaoJi_gbt27930_b_msg_charging_pause_evcc charging_pause_evcc;
    #endif
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_DISCHARGING == CONFIG_YES)
        // struct OpenChaoJi_gbt27930_b_msg_discharging_readiness_info_secc discharging_readiness_info_secc;
        struct OpenChaoJi_gbt27930_b_msg_discharging_readiness_info_evcc discharging_readiness_info_evcc;
        struct OpenChaoJi_gbt27930_b_msg_discharging_status_info_evcc discharging_status_info_evcc;
        struct OpenChaoJi_gbt27930_b_msg_discharging_basic_info_evcc discharging_basic_info_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_discharging_output_capability_secc discharging_output_capability_secc;
        // struct OpenChaoJi_gbt27930_b_msg_discharging_status_secc discharging_status_secc;
    #endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_STATISTICS == CONFIG_YES)
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_STATISTICS == CONFIG_YES)
        // struct OpenChaoJi_gbt27930_b_msg_statistics_secc statistics_secc;
        struct OpenChaoJi_gbt27930_b_msg_statistics_evcc statistics_evcc;
    #endif
#endif
        // struct OpenChaoJi_gbt27930_b_msg_phase_info_secc phase_info_secc;
        struct OpenChaoJi_gbt27930_b_msg_phase_ack_evcc phase_ack_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_relay_status_secc relay_status_secc;
        struct OpenChaoJi_gbt27930_b_msg_relay_status_evcc relay_status_evcc;
        struct OpenChaoJi_gbt27930_b_msg_latching_status_evcc latching_status_evcc;
        // struct OpenChaoJi_gbt27930_b_msg_stop_info_secc stop_info_secc;
        struct OpenChaoJi_gbt27930_b_msg_stop_info_evcc stop_info_evcc;
    } log_msg;
};

bool s_gbt_b_public_debug_enable = false;
void OpenChaoJi_debug_set_log_module_gbt_b_public(bool enable)
{
    s_gbt_b_public_debug_enable = enable;
}

/* -------------- 通用功能 鲁软 -------------- */
static int OpenChaoJi_gbt27930_b_evcc_parse_data(struct OpenChaoJi_evcc_context * context, struct OpenChaoJi_utility_data_buff_recv_data * recv_data);

/**
 * @brief: 停止系统定时器
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @return {*}
 */
static void OpenChaoJi_gbt27930_b_evcc_running_data_timer_reset(struct OpenChaoJi_evcc_context * context)
{
    LOG_NOTICE("[%d]STOP ALL TIMER", context->tag);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->trigger.Tv);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->func_nego.Tv);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->param_config.Tv);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.Tv);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.T1);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.T2);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_evin.Tv);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->self_check.Tv);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tv);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T2);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T3);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T4);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.State_Tv);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_Tv);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T1);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T2);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T3);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T4);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T5);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_Tv);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T1);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T2);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T3);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T4);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T5);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_Tv);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T1);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T2);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T3);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T4);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics.Tv);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->relay_status_evcc_T1);

    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->latching_status_T1);

    return;
}

/**
 * @brief: 重置系统运行数据
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @return {*}
 */
static void OpenChaoJi_gbt27930_b_evcc_running_data_reset(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_CHANGE("[%d]RESET RUNNING DATA", context->tag);

    // 启动参数需要临时备份一下, 否则从END状态不拔枪直接启动的情况会丢失启动参数
    struct OpenChaoJi_evcc_app_start_parameter app_start_parameter = context->running_data.b->app_start_parameter;

	memset(context->running_data.b, 0x00, sizeof(struct OpenChaoJi_evcc_gbt27930_b_data));

    context->running_data.b->func_nego.func_support_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_FUNC_NEGO_EVCC;

    context->running_data.b->param_config.param_config_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_PARAM_CONFIG_EVCC;
    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_RFID == CONFIG_YES)
    context->running_data.b->auth_rfid.rfid_wait_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_AUTH_RFID_WAIT_EVCC;
    #endif
    context->running_data.b->auth_evin.evin_param_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_AUTH_EVIN_PARAM_EVCC;

    context->running_data.b->charging.charging_ready_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_CHARGING_READY_EVCC;
    context->running_data.b->charging.charging_requirement_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_CHARGING_REQUIREMENT_EVCC;
    context->running_data.b->charging.charging_info_basic_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_CHARGING_INFO_BASIC_EVCC;
    context->running_data.b->charging.charging_info_battery_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_CHARGING_INFO_BATTERY_EVCC;
    context->running_data.b->charging.charging_pause_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_CHARGING_PAUSE_EVCC;

    context->running_data.b->statistics.statistics_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_STATISTICS_EVCC;

    context->running_data.b->phase_ack_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_PHASE_ACK_EVCC;
    context->running_data.b->stop_info_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_STOP_INFO_EVCC;
    context->running_data.b->relay_status_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_RELAY_STATUS_EVCC;
    context->running_data.b->latching_status_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_LATCHING_STATUS_EVCC;

    OpenChaoJi_gbt27930_b_evcc_running_data_timer_reset(context);

    // 恢复启动参数
    context->running_data.b->app_start_parameter = app_start_parameter;

    return;
}

/**
 * @brief: 系统复位
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @return {*}
 */
static void OpenChaoJi_gbt27930_b_evcc_reset_to_default(struct OpenChaoJi_evcc_context * context)
{
    LOG_WARNING("[%d] RESET TO DEFAULT", context->tag);

    OpenChaoJi_evcc_utility_session_reset(context->context_session);
    OpenChaoJi_evcc_utility_pilot_reset(context->context_pilot);

	OpenChaoJi_gbt27930_b_evcc_running_data_reset(context);
}

/**
 * @brief: 根据不同的消息类型更新系统上下文中的运行数据
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @param {OpenChaoJi_gbt27930_b_msg *} msg 包含消息数据的结构体指针
 * @return {true: 消息处理成功 false: 消息内容与当前记录一致无需更新}
 */
static bool OpenChaoJi_gbt27930_b_evcc_log_msg_set(struct OpenChaoJi_evcc_context * context, struct OpenChaoJi_gbt27930_b_msg * msg)
{
    switch (msg->pid)
    {
    case OPENCHAOJI_GBT27930_B_PGI_FUNC_NEGO_EVCC:
        if (memcmp(&context->running_data.b->log_msg.func_support_evcc, &msg->msg.func_support_evcc, sizeof(msg->msg.func_support_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.func_support_evcc, &msg->msg.func_support_evcc, sizeof(msg->msg.func_support_evcc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_PARAM_CONFIG_EVCC:
        if (memcmp(&context->running_data.b->log_msg.param_config_evcc, &msg->msg.param_config_evcc, sizeof(msg->msg.param_config_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.param_config_evcc, &msg->msg.param_config_evcc, sizeof(msg->msg.param_config_evcc));
            return true;
        }
        return false;
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_AUTH == CONFIG_YES)

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_RFID == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_AUTH_RFID_WAIT_EVCC:
        if (memcmp(&context->running_data.b->log_msg.auth_rfid_wait_evcc, &msg->msg.auth_rfid_wait_evcc, sizeof(msg->msg.auth_rfid_wait_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.auth_rfid_wait_evcc, &msg->msg.auth_rfid_wait_evcc, sizeof(msg->msg.auth_rfid_wait_evcc));
            return true;
        }
        return false;
    #endif

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_EVIN == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_AUTH_EVIN_PARAM_EVCC:
        if (memcmp(&context->running_data.b->log_msg.auth_evin_param_evcc, &msg->msg.auth_evin_param_evcc, sizeof(msg->msg.auth_evin_param_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.auth_evin_param_evcc, &msg->msg.auth_evin_param_evcc, sizeof(msg->msg.auth_evin_param_evcc));
            return true;
        }
        return false;
    #endif

#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_RESERVE == CONFIG_YES)

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_RESERVE_EVCC == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_RESERVE_INFO_EVCC:
        if (memcmp(&context->running_data.b->log_msg.reserve_info_evcc, &msg->msg.reserve_info_evcc, sizeof(msg->msg.reserve_info_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.reserve_info_evcc, &msg->msg.reserve_info_evcc, sizeof(msg->msg.reserve_info_evcc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_RESERVE_NEGO_EVCC:
        if (memcmp(&context->running_data.b->log_msg.reserve_nego_evcc, &msg->msg.reserve_nego_evcc, sizeof(msg->msg.reserve_nego_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.reserve_nego_evcc, &msg->msg.reserve_nego_evcc, sizeof(msg->msg.reserve_nego_evcc));
            return true;
        }
        return false;
    #endif

#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SELFCHECK == CONFIG_YES)

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SELFCHECK_GENERAL == CONFIG_YES)

    #endif

#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SUPPLY == CONFIG_YES)

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SUPPLY_BASIC == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_SUPPLY_STATUS_EVCC:
        if (memcmp(&context->running_data.b->log_msg.supply_status_evcc, &msg->msg.supply_status_evcc, sizeof(msg->msg.supply_status_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.supply_status_evcc, &msg->msg.supply_status_evcc, sizeof(msg->msg.supply_status_evcc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_SUPPLY_REQUIREMENT_EVCC:
        if (memcmp(&context->running_data.b->log_msg.supply_requirement_evcc, &msg->msg.supply_requirement_evcc, sizeof(msg->msg.supply_requirement_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.supply_requirement_evcc, &msg->msg.supply_requirement_evcc, sizeof(msg->msg.supply_requirement_evcc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_SUPPLY_FINISH_EVCC:
        if (memcmp(&context->running_data.b->log_msg.supply_finish_evcc, &msg->msg.supply_finish_evcc, sizeof(msg->msg.supply_finish_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.supply_finish_evcc, &msg->msg.supply_finish_evcc, sizeof(msg->msg.supply_finish_evcc));
            return true;
        }
        return false;
    #endif

#endif

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_CHARGING == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_READY_EVCC:
        if (memcmp(&context->running_data.b->log_msg.charging_ready_evcc, &msg->msg.charging_ready_evcc, sizeof(msg->msg.charging_ready_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.charging_ready_evcc, &msg->msg.charging_ready_evcc, sizeof(msg->msg.charging_ready_evcc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_REQUIREMENT_EVCC:
        if (memcmp(&context->running_data.b->log_msg.charging_requirement_evcc, &msg->msg.charging_requirement_evcc, sizeof(msg->msg.charging_requirement_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.charging_requirement_evcc, &msg->msg.charging_requirement_evcc, sizeof(msg->msg.charging_requirement_evcc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_INFO_BASIC_EVCC:
        if (memcmp(&context->running_data.b->log_msg.charging_info_basic_evcc, &msg->msg.charging_info_basic_evcc, sizeof(msg->msg.charging_info_basic_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.charging_info_basic_evcc, &msg->msg.charging_info_basic_evcc, sizeof(msg->msg.charging_info_basic_evcc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_INFO_BATTERY_EVCC:
        if (memcmp(&context->running_data.b->log_msg.charging_info_battery_evcc, &msg->msg.charging_info_battery_evcc, sizeof(msg->msg.charging_info_battery_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.charging_info_battery_evcc, &msg->msg.charging_info_battery_evcc, sizeof(msg->msg.charging_info_battery_evcc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_PAUSE_EVCC:
        if (memcmp(&context->running_data.b->log_msg.charging_pause_evcc, &msg->msg.charging_pause_evcc, sizeof(msg->msg.charging_pause_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.charging_pause_evcc, &msg->msg.charging_pause_evcc, sizeof(msg->msg.charging_pause_evcc));
            return true;
        }
        return false;
    #endif

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_DISCHARGING == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_READY_EVCC:
        if (memcmp(&context->running_data.b->log_msg.discharging_readiness_info_evcc, &msg->msg.discharging_readiness_info_evcc, sizeof(msg->msg.discharging_readiness_info_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.discharging_readiness_info_evcc, &msg->msg.discharging_readiness_info_evcc, sizeof(msg->msg.discharging_readiness_info_evcc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_REQUIREMENT_EVCC:
        // if (memcmp(&context->running_data.b->log_msg.discharging_output_capability_secc, &msg->msg.discharging_output_capability_secc, sizeof(msg->msg.discharging_output_capability_secc)) != 0)
        // {
        //     memcpy(&context->running_data.b->log_msg.discharging_output_capability_secc, &msg->msg.discharging_output_capability_secc, sizeof(msg->msg.discharging_output_capability_secc));
        //     return true;
        // }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_STATUS_EVCC:
        if (memcmp(&context->running_data.b->log_msg.discharging_status_info_evcc, &msg->msg.discharging_status_info_evcc, sizeof(msg->msg.discharging_status_info_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.discharging_status_info_evcc, &msg->msg.discharging_status_info_evcc, sizeof(msg->msg.discharging_status_info_evcc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_INFO_BASIC_EVCC:
        if (memcmp(&context->running_data.b->log_msg.discharging_basic_info_evcc, &msg->msg.discharging_basic_info_evcc, sizeof(msg->msg.discharging_basic_info_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.discharging_basic_info_evcc, &msg->msg.discharging_basic_info_evcc, sizeof(msg->msg.discharging_basic_info_evcc));
            return true;
        }
        return false;
    #endif


#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_STATISTICS == CONFIG_YES)

    #if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_STATISTICS == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_STATISTICS_EVCC:
        if (memcmp(&context->running_data.b->log_msg.statistics_evcc, &msg->msg.statistics_evcc, sizeof(msg->msg.statistics_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.statistics_evcc, &msg->msg.statistics_evcc, sizeof(msg->msg.statistics_evcc));
            return true;
        }
        return false;
    #endif

#endif
    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_PHASE_ACK_EVCC:
        if (memcmp(&context->running_data.b->log_msg.phase_ack_evcc, &msg->msg.phase_ack_evcc, sizeof(msg->msg.phase_ack_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.phase_ack_evcc, &msg->msg.phase_ack_evcc, sizeof(msg->msg.phase_ack_evcc));
            return true;
        }
        return true;    // 阶段确认报文比较重要, 每次都要打印
    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_RELAY_STATUS_EVCC:
        if (memcmp(&context->running_data.b->log_msg.relay_status_evcc, &msg->msg.relay_status_evcc, sizeof(msg->msg.relay_status_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.relay_status_evcc, &msg->msg.relay_status_evcc, sizeof(msg->msg.relay_status_evcc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_LATCHING_STATUS_EVCC:
        if (memcmp(&context->running_data.b->log_msg.latching_status_evcc, &msg->msg.latching_status_evcc, sizeof(msg->msg.latching_status_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.latching_status_evcc, &msg->msg.latching_status_evcc, sizeof(msg->msg.latching_status_evcc));
            return true;
        }
        return false;
    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_STOP_INFO_EVCC:
        if (memcmp(&context->running_data.b->log_msg.stop_info_evcc, &msg->msg.stop_info_evcc, sizeof(msg->msg.stop_info_evcc)) != 0)
        {
            memcpy(&context->running_data.b->log_msg.stop_info_evcc, &msg->msg.stop_info_evcc, sizeof(msg->msg.stop_info_evcc));
            return true;
        }
        return false;

    default: return false;
    }
}

/**
 * @brief: 通用报文发送
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @param {uint32_t} all 标签信息
 * @param {uint8_t *} data 待发送的数据
 * @param {uint16_t} data_len 数据长度
 * @return {int} 返回值 发送结果是否等于0
 */
static int OpenChaoJi_gbt27930_b_evcc_send_normal(struct OpenChaoJi_evcc_context * context, uint32_t all, uint8_t *data ,uint16_t data_len)
{
    struct OpenChaoJi_utility_data_buff_send_data send_data;
    send_data.tag.all = all;
    send_data.cnt = SEND_NORMAL_CNT_MACRO;
    send_data.interval_ms = SEND_NORMAL_INTERVAL_MS_MACRO;

    struct OpenChaoJi_gbt27930_b_msg msg;
    msg.pid = OPENCHAOJI_GBT27930_B_PID_FROM_TAG(all);
    memcpy(&msg.msg, data, data_len);

#if 0
    send_data.send_data.src_free = SEND_NORMAL_SRC_FREE_MACRO;
    send_data.send_data.data = data;
    send_data.send_data.len = data_len;
#else
    int dynamic_data_len = 0;
    unsigned char * dynamic_data = OpenChaoJi_gbt27930_b_msg_encode_data(&msg, &dynamic_data_len);
    if (dynamic_data == NULL)
    {
        return 0;
    }
    send_data.send_data.src_free = 0;
    send_data.send_data.data = dynamic_data;
    send_data.send_data.len = dynamic_data_len;
#endif

    bool changed = OpenChaoJi_gbt27930_b_evcc_log_msg_set(context, &msg);

    // 发送数据发生变化必须打出完整报文, 打印级别是INFO则把所有报文打印出来
    if ((changed) || ((OpenChaoJi_debug_get_log_level() & DBGL_INFO) != 0))
    {
        if ((msg.pid == OPENCHAOJI_GBT27930_B_PGI_PUBLIC_RELAY_STATUS_EVCC)     // RELAY 周期性报文, 即使INFO级别也不打印, 只变化才打印
        || (msg.pid == OPENCHAOJI_GBT27930_B_PGI_PUBLIC_LATCHING_STATUS_EVCC)
        )
        {
            if (!changed && !s_gbt_b_public_debug_enable)
            {
                goto SEND_DATA;
            }
        }

        OpenChaoJi_gbt27930_b_msg_log(&msg);
        if ((OpenChaoJi_debug_get_log_level() & DBGL_INFO) != 0)
        {
            LOG_DATA_NORMAL("->[%02X][%d]", msg.pid, send_data.send_data.len);
            LOG_DATA_BUFF_NORMAL(send_data.send_data.data, send_data.send_data.len);
        }
    }

SEND_DATA:
    return OpenChaoJi_evcc_utility_session_data_write(context->context_session, &send_data) != 0;
}

/**
 * @brief: 车辆阶段信息应答
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @param {uint8_t} fc_type fc
 * @param {uint8_t} fdc_type fdc
 * @return {*}
 */
static void OpenChaoJi_gbt27930_b_evcc_phase_ack_send(struct OpenChaoJi_evcc_context * context, uint8_t phase_ack)
{
	context->running_data.b->phase_info_secc_ok = 0;         // 置为0 等待下一次阶段信息报文

    context->running_data.b->phase_ack_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_PHASE_ACK_EVCC;
    context->running_data.b->phase_ack_evcc.phase_ack = phase_ack;

    OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_PHASE_ACK_EVCC, (uint8_t *)(&context->running_data.b->phase_ack_evcc), sizeof(context->running_data.b->phase_ack_evcc));

    return;
}

/**
 * @brief: 车俩中止报文发送
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @param {uint8_t} end_code 停机码
 * @param {uint8_t} end_Reason 停机原因
 * @return {*}
 */
static void OpenChaoJi_gbt27930_b_evcc_stop_info_send(struct OpenChaoJi_evcc_context * context, uint8_t end_code, uint8_t end_Reason)
{
    if (end_code != 0)
    {
        memset(&context->running_data.b->stop_info_evcc, 0, sizeof(context->running_data.b->stop_info_evcc));

        context->running_data.b->stop_info_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_STOP_INFO_EVCC;
        context->running_data.b->stop_info_evcc.end_code = end_code;
        if (end_Reason != 0)
        {
            context->running_data.b->stop_info_evcc.end_Reason = end_Reason;
        }
        // TODO: 故障码目前未定义
        // context->running_data.b->stop_info_evcc.fault_code  = (uint8_t *)&fault_code;

        OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_STOP_INFO_EVCC, (uint8_t *)(&context->running_data.b->stop_info_evcc), sizeof(context->running_data.b->stop_info_evcc));

        context->running_data.b->stop_info_evcc_sent = 1;
    }

    return;
}

/**
 * @brief: 车辆接触器状态信息发送
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @param {unsigned char} hal_relay_status 接触器状态
 * @return {*}
 */
static void OpenChaoJi_gbt27930_b_evcc_relay_info_send(struct OpenChaoJi_evcc_context * context, unsigned char hal_relay_status_evcc)
{
    memset(&context->running_data.b->relay_status_evcc, 0, sizeof(context->running_data.b->relay_status_evcc));

    context->running_data.b->relay_status_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_RELAY_STATUS_EVCC;
    context->running_data.b->relay_status_evcc.contact_c5 = (hal_relay_status_evcc & 0x02) ? OPENCHAOJI_GBT27930_B_CONTACT_STATUS_CLOSED : OPENCHAOJI_GBT27930_B_CONTACT_STATUS_OPENED;
    context->running_data.b->relay_status_evcc.contact_c6 = (hal_relay_status_evcc & 0x01) ? OPENCHAOJI_GBT27930_B_CONTACT_STATUS_CLOSED : OPENCHAOJI_GBT27930_B_CONTACT_STATUS_OPENED;

    OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_RELAY_STATUS_EVCC, (uint8_t *)(&context->running_data.b->relay_status_evcc), sizeof(context->running_data.b->relay_status_evcc));

    OpenChaoJi_os_soft_timer_reset(&context->running_data.b->relay_status_evcc_T1);

    return;
}

/**
 * @brief: 电子锁状态信息发送
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @param {unsigned char} hal_latching_status_evcc 锁状态
 * @return {*}
 */
static void OpenChaoJi_gbt27930_b_evcc_elock_info_send(struct OpenChaoJi_evcc_context * context, unsigned char hal_latching_status_evcc)
{
    memset(&context->running_data.b->latching_status_evcc, 0, sizeof(context->running_data.b->latching_status_evcc));

    context->running_data.b->latching_status_evcc.pid = OPENCHAOJI_GBT27930_B_PGI_PUBLIC_LATCHING_STATUS_EVCC;
    context->running_data.b->latching_status_evcc.latching_status = (hal_latching_status_evcc & 0x01) ? OPENCHAOJI_GBT27930_B_LATCHING_STATUS_TYPE_LOCKED : OPENCHAOJI_GBT27930_B_LATCHING_STATUS_TYPE_NOT_LOCK;

    OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_LATCHING_STATUS_EVCC, (uint8_t *)(&context->running_data.b->latching_status_evcc), sizeof(context->running_data.b->latching_status_evcc));

    OpenChaoJi_os_soft_timer_reset(&context->running_data.b->latching_status_T1);

    return;
}

/**
 * @brief: 正常停机处理
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @param {uint8_t} end_code 停机码
 * @param {uint8_t} end_Reason 停机原因
 * @return {int} 停机阶段跳转MODULE_STATUS_ID
 */
static int OpenChaoJi_gbt27930_b_evcc_stop_normal(struct OpenChaoJi_evcc_context * context, uint8_t end_code, uint8_t end_Reason)       // 正常停机
{
    if(context->running_data.b->stop_info_evcc_sent == 0)
    {
        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, end_code, end_Reason);
    }
    LOG_WARNING("[%d]InfoStopCharge", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S0_NORMAL;
}

/**
 * @brief: 故障停机处理
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @param {uint8_t} end_code 停机码
 * @param {uint8_t} end_Reason 停机原因
 * @return {int} 停机阶段跳转MODULE_STATUS_ID
 */
static int OpenChaoJi_gbt27930_b_evcc_stop_failed(struct OpenChaoJi_evcc_context * context, uint8_t end_code, uint8_t end_Reason)       // 故障停机
{
    if(context->running_data.b->stop_info_evcc_sent == 0)
    {
        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, end_code, end_Reason);
    }
    LOG_ERR("[%d]ErrStopCharge", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S1_FAULT;
}

/**
 * @brief: 紧急停机处理
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @param {uint8_t} end_code 停机码
 * @param {uint8_t} end_Reason 停机原因
 * @return {int} 停机阶段跳转MODULE_STATUS_ID
 */
static int OpenChaoJi_gbt27930_b_evcc_stop_emergency(struct OpenChaoJi_evcc_context * context, uint8_t end_code, uint8_t end_Reason)       // 紧急停机
{
    if(context->running_data.b->stop_info_evcc_sent == 0)
    {
        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, end_code, end_Reason);
    }
    LOG_EMERG("[%d]EmergencyStopCharge", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S2_EMRGE;
}

/**
 * @brief: 根据功能协商结果查找下一个支持的FDC
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @param {OpenChaoJi_gbt27930_b_FCType} cur_fc_type 当前FC
 * @return {int} 返回协商的下一个FDC+FC
 */
static int OpenChaoJi_gbt27930_b_evcc_find_next_support_fdc(struct OpenChaoJi_evcc_context * context, enum OpenChaoJi_gbt27930_b_FCType cur_fc_type)
{
	switch (cur_fc_type)
	{
    case OPENCHAOJI_GBT27930_B_FC_TYPE_FUNC_NEGO:
        return ((OPENCHAOJI_GBT27930_B_FDC_PARAM_CONFIG_GENERAL << 8 ) | OPENCHAOJI_GBT27930_B_FC_TYPE_PARAM_CONFIG);

	case OPENCHAOJI_GBT27930_B_FC_TYPE_PARAM_CONFIG:
		if(context->running_data.b->func_nego.func_support_evcc.fdc_auth != 0)
		{
			return ((context->running_data.b->func_nego.func_support_evcc.fdc_auth << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_AUTH);
		}
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_AUTH == CONFIG_YES)
	case OPENCHAOJI_GBT27930_B_FC_TYPE_AUTH:
		if(context->running_data.b->func_nego.func_support_evcc.fdc_reserve != 0)
		{
			return ((context->running_data.b->func_nego.func_support_evcc.fdc_reserve << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_RESERVE);
		}
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_RESERVE == CONFIG_YES)
	case OPENCHAOJI_GBT27930_B_FC_TYPE_RESERVE:
		if(context->running_data.b->func_nego.func_support_evcc.fdc_selfcheck != 0)
		{
			return ((context->running_data.b->func_nego.func_support_evcc.fdc_selfcheck << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_SELFCHECK);
		}
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SELFCHECK == CONFIG_YES)
	case OPENCHAOJI_GBT27930_B_FC_TYPE_SELFCHECK:
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SUPPLY == CONFIG_YES)
		if(context->running_data.b->func_nego.func_support_evcc.fdc_supply != 0)
		{
			return ((context->running_data.b->func_nego.func_support_evcc.fdc_supply << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_SUPPLY);
		}
#endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SUPPLY == CONFIG_YES)
	case OPENCHAOJI_GBT27930_B_FC_TYPE_SUPPLY:
#endif
		if(context->running_data.b->func_nego.func_support_evcc.fdc_energy != 0)
		{
			return ((context->running_data.b->func_nego.func_support_evcc.fdc_energy << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_ENERGY);
		}

	case OPENCHAOJI_GBT27930_B_FC_TYPE_ENERGY:
        // !!! 服务统计模块不管是否配置, 必须经过STOPPING状态, 保证安全停机

		// if(context->running_data.b->func_nego.func_support_evcc.fdc_statistics != 0)
		// {
		// 	return ((context->running_data.b->func_nego.func_support_evcc.fdc_statistics<<8)|OPENCHAOJI_GBT27930_B_FC_TYPE_STATISTICS);
		// }
		return ((1 << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_SERVICE_STOPPING);

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_STATISTICS == CONFIG_YES)
	case OPENCHAOJI_GBT27930_B_FC_TYPE_STATISTICS:
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SERVICE_IDLE == CONFIG_YES)
		if(context->running_data.b->func_nego.func_support_evcc.fdc_service_idle != 0)
		{
			return ((context->running_data.b->func_nego.func_support_evcc.fdc_service_idle<<8)|OPENCHAOJI_GBT27930_B_FC_TYPE_SERVICE_IDLE);
		}
#endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SERVICE_IDLE == CONFIG_YES)
	case OPENCHAOJI_GBT27930_B_FC_TYPE_SERVICE_IDLE:
#endif
	default:
		return ((1 << 8) | OPENCHAOJI_GBT27930_B_FC_TYPE_SERVICE_STOPPING);
	}
}
/**
 * @brief: 查找下一个支持的功能模块
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @return {OpenChaoJi_evcc_module *} 下一个功能模块状态表指针
 */
static const struct OpenChaoJi_evcc_module * OpenChaoJi_gbt27930_b_evcc_find_next_module(struct OpenChaoJi_evcc_context * context)
{
	uint16_t fdc_fc_next;
	uint8_t	 fdc;
	uint8_t  fc;

    const struct OpenChaoJi_evcc_module * curr_module = OpenChaoJi_evcc_service_find_module(context->evcc_gbt27930_system_b, context->current_module_status_id);
    enum OpenChaoJi_gbt27930_b_FCType cur_fc_type = curr_module->fc_type;

	fdc_fc_next = OpenChaoJi_gbt27930_b_evcc_find_next_support_fdc(context, cur_fc_type);
	fdc = fdc_fc_next>>8;
	fc = fdc_fc_next&0xFF;

    return OpenChaoJi_evcc_service_find_module_by_fdc(context->evcc_gbt27930_system_b, fc, fdc);
}
/**
 * @brief: 查找下一个功能模块的S0状态
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @return {int} 返回下一个模块s0状态ID
 */
static int OpenChaoJi_gbt27930_b_evcc_find_next_module_status(struct OpenChaoJi_evcc_context * context)
{
    const struct OpenChaoJi_evcc_module * next_module = OpenChaoJi_gbt27930_b_evcc_find_next_module(context);

    return OPENCHAOJI_EVCC_MODULE_STATUS_ID(next_module->module_id, 0);
}
/**
 * @brief: 检查SECC的阶段信息报文是否符合功能协商结果
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @return {int} 1:确认成功 0:确认失败
 */
static int OpenChaoJi_gbt27930_b_evcc_check_next_phase_info(struct OpenChaoJi_evcc_context * context)
{
    if (!context->running_data.b->phase_info_secc_ok)
    {
        return 0;
    }

    const struct OpenChaoJi_evcc_module * next_module = OpenChaoJi_gbt27930_b_evcc_find_next_module(context);
	LOG_INFO("next FC:%X | next FDC:%X | phase_info FC:%X | phase FDC:%X",next_module->fc_type,next_module->fdc_type,context->running_data.b->phase_info_secc.fc_type,context->running_data.b->phase_info_secc.fdc_type);
    if (next_module->fc_type == context->running_data.b->phase_info_secc.fc_type
    && next_module->fdc_type == context->running_data.b->phase_info_secc.fdc_type)
    {
        return 1;
    }

    return 0;
}


/* -------------- IDLE 模块 特来电 -------------- */
void OpenChaoJi_gbt27930_b_evcc_prev_idle_s0_idle(struct OpenChaoJi_evcc_context * context)
{
    OpenChaoJi_gbt27930_b_evcc_reset_to_default(context);
}
#define OpenChaoJi_gbt27930_b_evcc_post_idle_s0_idle         NULL
// static void OpenChaoJi_gbt27930_b_evcc_prev_idle_s0_idle(struct OpenChaoJi_evcc_context * context);
// static void OpenChaoJi_gbt27930_b_evcc_post_idle_s0_idle(struct OpenChaoJi_evcc_context * context);
static int  OpenChaoJi_gbt27930_b_evcc_loop_idle_s0_idle(struct OpenChaoJi_evcc_context * context)
{
    if (context->app_permit_charge)
    {
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S0_CONFIRM_CONNECT;
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_IDLE_S0_IDLE;
}

const struct OpenChaoJi_evcc_module_status c_sytem_b_evcc_status_array_idle[OPENCHAOJI_GBT27930_B_EVCC_STATUS_IDLE_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_IDLE_S0_IDLE,
        .name = "Idle.S0.Idle",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_idle_s0_idle,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_idle_s0_idle,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_idle_s0_idle,
    },
};

const struct OpenChaoJi_evcc_module c_gbt27930_b_evcc_module_idle =
{
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_IDLE,
    .fc_type = 0,
    .fdc_type = 1,
    .name = "IDLE",
    .status_array = c_sytem_b_evcc_status_array_idle,
    .status_array_len = OPENCHAOJI_GBT27930_B_EVCC_STATUS_IDLE_NUM,
};




/* -------------- Trigger 模块 特来电 -------------- */
/**
 * T0 : 确认连接, 电子锁自然打开, S2常开, Sv S2p设为电动汽车厂家默认状态
 *      检测点2电压由0V->10.8V(或2.34V), 则车辆被唤醒(电动汽车闭合Sv), 进入T1
 */
static void OpenChaoJi_gbt27930_b_evcc_prev_trigger_s0_confirm_connect(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_PREV("[%d]Trigger.s0.prev:Unlock & S2.Open", context->tag);
    OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle, 0);         // 电子锁自然打开
    OpenChaoJi_evcc_utility_pilot_b_permit_charge(context->context_pilot, false);  // S2常开

    // Sv S2p设为电动汽车厂家默认状态
}
static void OpenChaoJi_gbt27930_b_evcc_post_trigger_s0_confirm_connect(struct OpenChaoJi_evcc_context * context)
{

}
static int  OpenChaoJi_gbt27930_b_evcc_loop_trigger_s0_confirm_connect(struct OpenChaoJi_evcc_context * context)
{
    // 永远等待插枪, 直到检测点2电压由0V->10.8V(或2.34V)
    enum OpenChaoJi_pilot_status_gbt18487_b status = OpenChaoJi_evcc_utility_pilot_status_b(context->context_pilot);
    if ((status == OPENCHAOJI_PILOT_STATUS_GBT18487_B_Ap) || (status == OPENCHAOJI_PILOT_STATUS_GBT18487_B_B))
    {
        LOG_STATUS_CHANGE("[%d]Trigger.S0:secc connected", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S1_CONFIRM_SECC_TYPE;
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S0_CONFIRM_CONNECT;
}
/**
 * T1 : 确认SECC类型, 电动汽车闭合Sv(无论Sv是常开还是常闭, 在T1时刻前应闭合)
 *      检测点3电压为U2的一半, 确认CC2回路连接且连接的是B类系统的SECC
 */
static void OpenChaoJi_gbt27930_b_evcc_prev_trigger_s1_confirm_secc_type(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_PREV("[%d]Trigger.s1.prev:Wakeup & close Sv", context->tag);
    OpenChaoJi_evcc_utility_pilot_wakeup_success(context->context_pilot);   // 18487.C.4.2.1, 对于开关Sv初始化状态为断开的电动汽车, 被唤醒后车辆控制器应闭合开关Sv。

    LOG_STATUS_PREV("[%d]Trigger.s1.prev:Start Tv", context->tag);
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->trigger.Tv, SYSTEM_PILOT_SECC_TYPE_TIME_OUT);
}
static void OpenChaoJi_gbt27930_b_evcc_post_trigger_s1_confirm_secc_type(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_POST("[%d]Trigger.s1.post:Stop Tv", context->tag);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->trigger.Tv);
}
static int  OpenChaoJi_gbt27930_b_evcc_loop_trigger_s1_confirm_secc_type(struct OpenChaoJi_evcc_context * context)
{
    enum OpenChaoJi_secc_gbt27930_type secc_type = OpenChaoJi_evcc_utility_pilot_b_connected_secc_type(context->context_pilot);
    if (secc_type == OPENCHAOJI_SECC_GBT27930_TYPE_B)
    {
        LOG_STATUS_CHANGE("[%d]Trigger.s1:connect secc type is B", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S2_FULL_CONNECT;
    }
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)
    if (secc_type == OPENCHAOJI_SECC_GBT27930_TYPE_A)
    {
        if (context->secc_gbt27930_type_compatibility & OPENCHAOJI_SECC_GBT27930_TYPE_A)
        {
            LOG_STATUS_CHANGE("[%d]Trigger.s1:connect secc type is A", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_SA_SYSMTEM_A;
        }
        else
        {
            LOG_ALERT("[%d]Trigger.s1:secc type is A, but not support", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S0_FINISHING;
        }
    }
#endif

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->trigger.Tv))
    {
        LOG_ALERT("[%d]Trigger.s1:unknown secc type, timeout", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S0_FINISHING;
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S1_CONFIRM_SECC_TYPE;
}

/**
 * T2 : 确认SECC类型成功后, 允许完全连接
 *      闭合S2p, 此时检测点2的电压为2.34V
 */
static void OpenChaoJi_gbt27930_b_evcc_prev_trigger_s2_full_connect(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_PREV("[%d]Trigger.s2.prev:confirm secc type b", context->tag);
    OpenChaoJi_evcc_utility_pilot_b_confirm_secc_tyep_b(context->context_pilot);    // 18487.C.4.2.1, 确认充电机类型后, 闭合S2p
}
static void OpenChaoJi_gbt27930_b_evcc_post_trigger_s2_full_connect(struct OpenChaoJi_evcc_context * context)
{

}
static int  OpenChaoJi_gbt27930_b_evcc_loop_trigger_s2_full_connect(struct OpenChaoJi_evcc_context * context)
{
    // 等待检测点2电压为2.34V
    enum OpenChaoJi_pilot_status_gbt18487_b status = OpenChaoJi_evcc_utility_pilot_status_b(context->context_pilot);
    if (status == OPENCHAOJI_PILOT_STATUS_GBT18487_B_B)
    {
        LOG_STATUS_CHANGE("[%d]Trigger.s2:state b, full connect", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S3_CONFIRM_SECC_READY;
    }
    // TODO: timeout 需要18487规范进行解释

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S2_FULL_CONNECT;
}
/**
 * T3 : 等待SECC准备就绪,
 *      检测点2电压为8.73V
 *      如未检测到S1开关闭合状态, 电动汽车可进入休眠
 */
static void OpenChaoJi_gbt27930_b_evcc_prev_trigger_s3_confirm_secc_ready(struct OpenChaoJi_evcc_context * context)
{

}
static void OpenChaoJi_gbt27930_b_evcc_post_trigger_s3_confirm_secc_ready(struct OpenChaoJi_evcc_context * context)
{

}
static int  OpenChaoJi_gbt27930_b_evcc_loop_trigger_s3_confirm_secc_ready(struct OpenChaoJi_evcc_context * context)
{
    // 等待检测点2电压为8.73V
    enum OpenChaoJi_pilot_status_gbt18487_b status = OpenChaoJi_evcc_utility_pilot_status_b(context->context_pilot);
    if (status == OPENCHAOJI_PILOT_STATUS_GBT18487_B_C)
    {
        LOG_STATUS_CHANGE("[%d]Trigger.s3:state c, secc s1 closed", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S4_SESSION;
    }
    // TODO: 如未检测到S1开关闭合状态, 电动汽车可进入休眠

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S3_CONFIRM_SECC_READY;
}
/**
 * T4 : 版本协商, 建立会话连接
 *      如未收到版本协商报文, 电动汽车可进入休眠
 */
static void OpenChaoJi_gbt27930_b_evcc_prev_trigger_s4_session(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_PREV("[%d]Trigger.s4.prev:start session", context->tag);
    OpenChaoJi_evcc_utility_session_start(context->context_session);    // 18487.C.4.3, 启动数据连接, 开始进行通信版本协商

    LOG_STATUS_PREV("[%d]Trigger.s4.prev:start Tv", context->tag);
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->trigger.Tv, SYSTEM_PILOT_WAIT_SESSION_TIME_OUT); //超时时间大于版本协商时间+1s
}
static void OpenChaoJi_gbt27930_b_evcc_post_trigger_s4_session(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_POST("[%d]Trigger.s4.post:stop Tv", context->tag);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->trigger.Tv);
}
static int  OpenChaoJi_gbt27930_b_evcc_loop_trigger_s4_session(struct OpenChaoJi_evcc_context * context)
{
    enum OpenChaoJi_evcc_utility_session_connect_status session_connect = OpenChaoJi_evcc_utility_session_is_connected(context->context_session);
    if (session_connect == OPENCHAOJI_EVCC_UTILITY_SESSION_CONNECT_STATUS_CONNECTED)
    {
		LOG_STATUS_CHANGE("[%d]Trigger.s4:version negotiation success, session connected", context->tag);
    	return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S1_NEGO; // 18487.C.4.3 传输数据连接已建立且链路层版本协商成功
    }

    if (session_connect == OPENCHAOJI_EVCC_UTILITY_SESSION_CONNECT_STATUS_DISCONNECTED)
    {
        LOG_STATUS_CHANGE("[%d]Trigger.s4:version negotiation fault, exit");
        return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, 0, 0);
    }

    if(OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->trigger.Tv))
    {
        LOG_STATUS_CHANGE("[%d]Trigger.s4:version negotiation timeout, exit");
        return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, 0, 0);
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S4_SESSION;
}

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)
static void OpenChaoJi_gbt27930_b_evcc_prev_trigger_sa_system_a(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_PREV("[%d]Trigger.sa.prev:confirm secc type a", context->tag);
    OpenChaoJi_evcc_utility_pilot_b_confirm_secc_tyep_a(context->context_pilot);
}
static void OpenChaoJi_gbt27930_b_evcc_post_trigger_sa_system_a(struct OpenChaoJi_evcc_context * context)
{

}
static int  OpenChaoJi_gbt27930_b_evcc_loop_trigger_sa_system_a(struct OpenChaoJi_evcc_context * context)
{
    // 进入该状态, 等待service切换系统A
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_SA_SYSMTEM_A;
}
#endif

const struct OpenChaoJi_evcc_module_status c_sytem_b_evcc_status_array_trigger[OPENCHAOJI_GBT27930_B_EVCC_STATUS_TRIGGER_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S0_CONFIRM_CONNECT,
        .name = "Trigger.S0.ConfirmConnect",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_trigger_s0_confirm_connect,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_trigger_s0_confirm_connect,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_trigger_s0_confirm_connect,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S1_CONFIRM_SECC_TYPE,
        .name = "Trigger.S1.ConfirmSeccType",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_trigger_s1_confirm_secc_type,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_trigger_s1_confirm_secc_type,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_trigger_s1_confirm_secc_type,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S2_FULL_CONNECT,
        .name = "Trigger.S2.FullConnect",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_trigger_s2_full_connect,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_trigger_s2_full_connect,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_trigger_s2_full_connect,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S3_CONFIRM_SECC_READY,
        .name = "Trigger.S3.ConfirmSeccReady",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_trigger_s3_confirm_secc_ready,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_trigger_s3_confirm_secc_ready,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_trigger_s3_confirm_secc_ready,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S4_SESSION,
        .name = "Trigger.S4.Session",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_trigger_s4_session,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_trigger_s4_session,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_trigger_s4_session,
    },
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_SA_SYSMTEM_A,
        .name = "Trigger.SA.SystemA",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_trigger_sa_system_a,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_trigger_sa_system_a,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_trigger_sa_system_a,
    }
#endif
};

const struct OpenChaoJi_evcc_module c_gbt27930_b_evcc_module_trigger =
{
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_TRIGGER,
    .fc_type = 1,
    .fdc_type = 1,
    .name = "TRIGGER",
    .status_array = c_sytem_b_evcc_status_array_trigger,
    .status_array_len = OPENCHAOJI_GBT27930_B_EVCC_STATUS_TRIGGER_NUM,
};

/* -------------- 功能协商 模块 嘉盛 -------------- */

// 车端根据自己的优先级列表, 依次查找app下发的fdc是否在桩的重载列表中
static int OpenChaoJi_gbt27930_b_evcc_func_nego_select_fdc(uint8_t fdc_secc[8], uint8_t fdc_evcc_app[8])
{
    for (int i = 0; i < 8; i++)
    {
        if (fdc_evcc_app[i] == 0)
        {
            continue;
        }

		if(fdc_secc[i] == fdc_evcc_app[i])
		{
            return (i+1);
		}
    }

    return 0;
}

// 根据secc给出的support状态, 计算evcc的最终选择的fdc填入func_support_evcc, 协商成功(所有的必选项已选择)返回1,否则返回0
static int OpenChaoJi_gbt27930_b_evcc_func_nego(struct OpenChaoJi_evcc_context * context)
{
    // 鉴权的判断
    // 车先判断是否支持此fc
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_AUTH == CONFIG_YES)
    context->running_data.b->func_nego.func_support_evcc.fdc_auth = OpenChaoJi_gbt27930_b_evcc_func_nego_select_fdc(context->running_data.b->func_nego.func_support_secc.fdc_support_auth, context->running_data.b->app_start_parameter.fdc_auth);
#endif

    // 预约的判断
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_RESERVE == CONFIG_YES)
    context->running_data.b->func_nego.func_support_evcc.fdc_reserve = OpenChaoJi_gbt27930_b_evcc_func_nego_select_fdc(context->running_data.b->func_nego.func_support_secc.fdc_support_reserve, context->running_data.b->app_start_parameter.fdc_reserve);
#endif

    // 系统自检的判断
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SELFCHECK == CONFIG_YES)
    context->running_data.b->func_nego.func_support_evcc.fdc_selfcheck = OpenChaoJi_gbt27930_b_evcc_func_nego_select_fdc(context->running_data.b->func_nego.func_support_secc.fdc_support_selfcheck, context->running_data.b->app_start_parameter.fdc_selfcheck);
#endif

    // 供电模式的判断
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SUPPLY == CONFIG_YES)
    context->running_data.b->func_nego.func_support_evcc.fdc_supply = OpenChaoJi_gbt27930_b_evcc_func_nego_select_fdc(context->running_data.b->func_nego.func_support_secc.fdc_support_supply, context->running_data.b->app_start_parameter.fdc_supply);
#endif

    // 预充及能量传输的判断
    context->running_data.b->func_nego.func_support_evcc.fdc_energy = OpenChaoJi_gbt27930_b_evcc_func_nego_select_fdc(context->running_data.b->func_nego.func_support_secc.fdc_support_energy, context->running_data.b->app_start_parameter.fdc_energy);

    // 服务统计的判断  (停止中的不在fdc结构体里所以暂时没有加)
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_STATISTICS == CONFIG_YES)
    context->running_data.b->func_nego.func_support_evcc.fdc_statistics = OpenChaoJi_gbt27930_b_evcc_func_nego_select_fdc(context->running_data.b->func_nego.func_support_secc.fdc_support_statistics, context->running_data.b->app_start_parameter.fdc_statistics);
#endif

    // 服务空闲的判断 (需要判断吗，是否始终是有这个fdc)
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SERVICE_IDLE == CONFIG_YES)
    context->running_data.b->func_nego.func_support_evcc.fdc_service_idle = OpenChaoJi_gbt27930_b_evcc_func_nego_select_fdc(context->running_data.b->func_nego.func_support_secc.fdc_support_service_idle, context->running_data.b->app_start_parameter.fdc_service_idle);
#endif

    // 再次判断必须项
    if (context->running_data.b->func_nego.func_support_evcc.fdc_selfcheck > 0 && context->running_data.b->func_nego.func_support_evcc.fdc_energy > 0)
    {
        return 1;
    }

    return 0;
}

static void OpenChaoJi_gbt27930_b_evcc_prev_func_nego_s1_nego(struct OpenChaoJi_evcc_context * context)
{
    // 文档的S1第一个动作（发送"车辆版本协商结果"帧）不在此处发送, 链路层已经发送完成。
    LOG_STATUS_PREV("[%d]Nego S1 Send EVCC Version message", context->tag);

    // 打开Tv
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->func_nego.Tv, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_FUNC_NEGO_EVCC);
    LOG_STATUS_PREV("[%d]Nego S1 Tv start", context->tag);

}
#define OpenChaoJi_gbt27930_b_evcc_post_func_nego_s1_nego         NULL
static int OpenChaoJi_gbt27930_b_evcc_loop_func_nego_s1_nego(struct OpenChaoJi_evcc_context * context)
{
    // 接收"充电机支持功能"报文
    if (context->running_data.b->func_nego.func_support_secc_ok)
    {
        LOG_DATA_CHANGE("[%d]Nego S1 SECC Supported Model received", context->tag);

        int nego_result = OpenChaoJi_gbt27930_b_evcc_func_nego(context);
        if (nego_result)
        {
            OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_FUNC_NEGO_EVCC, (uint8_t *)(&context->running_data.b->func_nego.func_support_evcc), sizeof(context->running_data.b->func_nego.func_support_evcc));

            LOG_STATUS_CHANGE("[%d]Nego S1 Send EVCC Nego Result message success", context->tag);

            // 进入S2
            LOG_STATUS_CHANGE("[%d]Nego S1 To S2", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S2_PHASE_CONFIRM;
        }
        else
        {
            OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_FUNC_NEGO_EVCC, (uint8_t *)(&context->running_data.b->func_nego.func_support_evcc), sizeof(context->running_data.b->func_nego.func_support_evcc));
            LOG_STATUS_CHANGE("[%d]Nego S1 Send EVCC Nego Result message fail", context->tag);

            // 进入S4
            LOG_STATUS_CHANGE("[%d]Nego S1 To S4", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S4_FAIL;
        }
    }
    // Tv定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->func_nego.Tv))
    {
        LOG_STATUS_CHANGE("[%d]Nego S1 Tv Timeout", context->tag);
        // 发送"中止_功能协商超时"报文
        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_FUNC_NEGO);
        LOG_STATUS_CHANGE("[%d]Nego S1 Send Nego Timeout message", context->tag);

        // 进入S4
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S4_FAIL;
    }

    // 未收到, 未超时, 继续等待
    LOG_STATUS_LOOP("[%d]Nego S1 Loop", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S1_NEGO;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_func_nego_s2_confirm   NULL
#define OpenChaoJi_gbt27930_b_evcc_post_func_nego_s2_confirm   NULL
static int OpenChaoJi_gbt27930_b_evcc_loop_func_nego_s2_confirm(struct OpenChaoJi_evcc_context * context)
{
    // 接收"充电机阶段信息"报文
    if (context->running_data.b->phase_info_secc_ok)
    {
        LOG_DATA_CHANGE("[%d]Nego S2 Receive SECC Phase Information message", context->tag);

        // 车辆判断是否支持
        if (OpenChaoJi_gbt27930_b_evcc_check_next_phase_info(context))
        {
            // 发送"车辆阶段确认_成功"报文
            OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED);
            LOG_STATUS_CHANGE("[%d]Nego S2 Send EVCC Phase Confirm Success message", context->tag);

            // 进入S3
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S3_SUCCEED;
        }
        else
        {
            // 发送"车辆阶段确认_失败"报文
            OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_FAILED);
            LOG_STATUS_CHANGE("[%d]Nego S2 Send EVCC Phase Confirm Error message", context->tag);

            // 进入S4
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S4_FAIL;
        }
    }

    // 接收"中止_功能协商失败"报文
    if (context->running_data.b->stop_info_secc_ok)
    {
        LOG_STATUS_CHANGE("[%d]Nego S2 Receive Nego Error message", context->tag);
        if (context->running_data.b->stop_info_secc.end_Reason == OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_FUNC_NEGO)
        {
            // 进入S4
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S4_FAIL;
        }
    }

    // 未收到, 继续等待
    LOG_STATUS_LOOP("[%d]Nego S2 Loop", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S2_PHASE_CONFIRM;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_func_nego_s3_succeed NULL
#define OpenChaoJi_gbt27930_b_evcc_post_func_nego_s3_succeed NULL
static int OpenChaoJi_gbt27930_b_evcc_loop_func_nego_s3_succeed(struct OpenChaoJi_evcc_context *context)
{
    // 关闭Tv定时器
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->func_nego.Tv);
    LOG_STATUS_CHANGE("[%d]Param Config S3 Tv close", context->tag);

    // 进入参数配置功能模块FDC
    return OpenChaoJi_gbt27930_b_evcc_find_next_module_status(context);
}

#define OpenChaoJi_gbt27930_b_evcc_prev_func_nego_s4_failed NULL
#define OpenChaoJi_gbt27930_b_evcc_post_func_nego_s4_failed NULL
static int OpenChaoJi_gbt27930_b_evcc_loop_func_nego_s4_failed(struct OpenChaoJi_evcc_context *context)
{
    // 关闭Tv定时器
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->func_nego.Tv);
    LOG_STATUS_CHANGE("[%d]Param Config S4 Tv close", context->tag);

    // 退出充电过程
    return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_FAILED_FUNC_NEGO);
}

const struct OpenChaoJi_evcc_module_status c_sytem_b_evcc_status_array_func_nego[OPENCHAOJI_GBT27930_B_EVCC_STATUS_FUNC_NEGO_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S1_NEGO,
        .name = "Nego.S1.Nego",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_func_nego_s1_nego,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_func_nego_s1_nego,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_func_nego_s1_nego,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S2_PHASE_CONFIRM,
        .name = "Nego.S2.Phase Confirm",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_func_nego_s2_confirm,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_func_nego_s2_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_func_nego_s2_confirm,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S3_SUCCEED,
        .name = "Nego.S3.Succeed",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_func_nego_s3_succeed,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_func_nego_s3_succeed,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_func_nego_s3_succeed,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S4_FAIL,
        .name = "Nego.S4.Fail",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_func_nego_s4_failed,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_func_nego_s4_failed,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_func_nego_s4_failed,
    },
};

const struct OpenChaoJi_evcc_module c_gbt27930_b_evcc_module_func_nego =
    {
        .name = "Func_Nego",
        .module_id = OPENCHAOJI_GBT27930_B_MODULE_FUNC_NEGO,
        .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_FUNC_NEGO,
        .fdc_type = OPENCHAOJI_GBT27930_B_FDC_FUNC_NEGO_GENERAL,
        .status_array = c_sytem_b_evcc_status_array_func_nego,
        .status_array_len = OPENCHAOJI_GBT27930_B_EVCC_STATUS_FUNC_NEGO_NUM,
};

/* -------------- 参数配置 模块 嘉盛 -------------- */
#define OpenChaoJi_gbt27930_b_evcc_prev_param_config_s0_init NULL
#define OpenChaoJi_gbt27930_b_evcc_post_param_config_s0_init NULL
static int OpenChaoJi_gbt27930_b_evcc_loop_param_config_s0_init(struct OpenChaoJi_evcc_context *context)
{
    // 打开TV
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->param_config.Tv, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_FUNC_PARAM_CONFIG_EVCC);
    LOG_STATUS_CHANGE("[%d]Param Config S0 Tv start", context->tag);

    // 进入S1
    LOG_STATUS_CHANGE("[%d]Param Config S0 To S1", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S1_CONFIG;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_param_config_s1_config NULL
#define OpenChaoJi_gbt27930_b_evcc_post_param_config_s1_config NULL
static int OpenChaoJi_gbt27930_b_evcc_loop_param_config_s1_config(struct OpenChaoJi_evcc_context *context)
{
    // 接收"充电机充电参数"报文
    if (context->running_data.b->param_config.param_config_secc_ok)
    {
        LOG_DATA_NORMAL("[%d]Param Config S1 Receive SECC Charging Param message", context->tag);

        // 充电参数匹配判断
        if (context->running_data.b->app_start_parameter.parameter_max_charging_volt >= context->running_data.b->param_config.param_config_secc.parameter_min_charging_volt &&
            context->running_data.b->app_start_parameter.parameter_max_charging_curr >= context->running_data.b->param_config.param_config_secc.parameter_min_charging_curr)
        {
            // 发送"车辆充电参数"报文
            context->running_data.b->param_config.param_config_evcc.parameter_max_charging_curr = context->running_data.b->app_start_parameter.parameter_max_charging_curr;
            context->running_data.b->param_config.param_config_evcc.parameter_max_charging_volt = context->running_data.b->app_start_parameter.parameter_max_charging_volt;
            context->running_data.b->param_config.param_config_evcc.parameter_max_charging_energy = context->running_data.b->app_start_parameter.parameter_max_charging_energy;
            context->running_data.b->param_config.param_config_evcc.parameter_soc = context->running_data.b->app_start_parameter.parameter_soc;
            context->running_data.b->param_config.param_config_evcc.parameter_max_battery_volt = context->running_data.b->app_start_parameter.parameter_max_battery_volt;
            context->running_data.b->param_config.param_config_evcc.parameter_max_battery_temperature = context->running_data.b->app_start_parameter.parameter_max_battery_temperature;
            context->running_data.b->param_config.param_config_evcc.parameter_max_discharge_energy = context->running_data.b->app_start_parameter.parameter_max_discharge_energy;
            context->running_data.b->param_config.param_config_evcc.parameter_min_discharge_volt = context->running_data.b->app_start_parameter.parameter_min_discharge_volt;
            context->running_data.b->param_config.param_config_evcc.parameter_max_discharge_curr = context->running_data.b->app_start_parameter.parameter_max_discharge_curr;
            context->running_data.b->param_config.param_config_evcc.parameter_min_discharge_curr = context->running_data.b->app_start_parameter.parameter_min_discharge_curr;

            OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_FUNC_PARAM_CONFIG_EVCC, (uint8_t *)(&context->running_data.b->param_config.param_config_evcc), sizeof(context->running_data.b->param_config.param_config_evcc));
            LOG_STATUS_CHANGE("[%d]Param Config S1 Send EVCC Charging Param message", context->tag);

            // 进入S2
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S2_PHASE_CONFIRM;
        }
        else
        {
            // 发送"中止_充电参数不匹配"报文
            OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_FAILED_PARAM_CONFIG);
            LOG_STATUS_CHANGE("[%d]Param Config S1 Send Charging Param Not Matched", context->tag);

            // 进入S4（协议的"车辆状态转换表"里面写的是进入S3, 需要记录汇总后提交）
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S4_FAIL;
        }
    }

    // Tv定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->param_config.Tv))
    {
        LOG_STATUS_CHANGE("[%d]Param Config S1 Tv timeout", context->tag);

        // 发送"中止_参数配置超时"报文
        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_PARAM_CONFIG);
        LOG_STATUS_CHANGE("[%d]Param Config S1 Send Param Config Timeout message", context->tag);

        // 进入S4
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S4_FAIL;
    }

    // 未收到, 未超时, 继续等待
    LOG_STATUS_LOOP("[%d]Param Config S1 Loop", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S1_CONFIG;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_param_config_s2_confirm NULL
#define OpenChaoJi_gbt27930_b_evcc_post_param_config_s2_confirm NULL
static int OpenChaoJi_gbt27930_b_evcc_loop_param_config_s2_confirm(struct OpenChaoJi_evcc_context *context)
{
    // 接收"充电机阶段信息"报文
    if (context->running_data.b->phase_info_secc_ok)
    {
        LOG_STATUS_CHANGE("[%d]Param Config S2 Receive SECC", context->tag);

        // 车辆判断是否支持
        if (OpenChaoJi_gbt27930_b_evcc_check_next_phase_info(context))
        {
            // 发送"车辆阶段确认_成功"报文
            OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED);
            LOG_STATUS_CHANGE("[%d]Param Config S2 Send EVCC Phase Config Success message", context->tag);

            // 进入S3
            LOG_STATUS_CHANGE("[%d]Param Config S2 To S3", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S3_SUCCEED;
        }
        else
        {
            // 发送"车辆阶段确认_失败"报文
            OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_FAILED);
            LOG_STATUS_CHANGE("[%d]Param Config S2 Send EVCC Phase Config Error message", context->tag);

            // 进入S4
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S4_FAIL;
        }
    }

    // 接收"中止_参数不匹配"报文
    if (context->running_data.b->stop_info_secc_ok)
    {
        if (context->running_data.b->stop_info_secc.end_Reason == OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_PARAM_CONFIG)
        {
            LOG_STATUS_CHANGE("[%d]Param Config S2 Receive Param Not Matched message", context->tag);
            // 进入S4
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S4_FAIL;
        }
    }

    // Tv定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->param_config.Tv))
    {
        LOG_STATUS_CHANGE("[%d]Param Config S2 Tv timeout", context->tag);

        // 发送"中止_参数配置超时"报文
        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_PARAM_CONFIG);
        LOG_STATUS_CHANGE("[%d]Param Config S2 Send Param Config Timeout message", context->tag);

        // 进入S4
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S4_FAIL;
    }

    // 未收到, 未超时, 继续等待
    LOG_STATUS_LOOP("[%d]Param Config S2 Loop", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S2_PHASE_CONFIRM;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_param_config_s3_succeed NULL
#define OpenChaoJi_gbt27930_b_evcc_post_param_config_s3_succeed NULL
static int OpenChaoJi_gbt27930_b_evcc_loop_param_config_s3_succeed(struct OpenChaoJi_evcc_context *context)
{
    // 关闭Tv定时器
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->param_config.Tv);
    LOG_STATUS_CHANGE("[%d]Param Config S3 Tv close", context->tag);

    // 根据功能协商结果进入下一功能模块FDC
    return OpenChaoJi_gbt27930_b_evcc_find_next_module_status(context);
}

#define OpenChaoJi_gbt27930_b_evcc_prev_param_config_s4_failed NULL
#define OpenChaoJi_gbt27930_b_evcc_post_param_config_s4_failed NULL
static int OpenChaoJi_gbt27930_b_evcc_loop_param_config_s4_failed(struct OpenChaoJi_evcc_context *context)
{
    // 关闭Tv定时器
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->param_config.Tv);
    LOG_STATUS_CHANGE("[%d]Param Config S4 Tv close", context->tag);

    // 退出充电过程
    return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_FAILED_PARAM_CONFIG);
}

const struct OpenChaoJi_evcc_module_status c_sytem_b_evcc_status_array_param_config[OPENCHAOJI_GBT27930_B_EVCC_STATUS_PARAM_CONFIG_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S0_INIT,
        .name = "Param Config.S0.Init",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_param_config_s0_init,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_param_config_s0_init,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_param_config_s0_init,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S1_CONFIG,
        .name = "Param Config.S1.Config",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_param_config_s1_config,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_param_config_s1_config,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_param_config_s1_config,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S2_PHASE_CONFIRM,
        .name = "Param Config.S2.Phase Confirm",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_param_config_s2_confirm,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_param_config_s2_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_param_config_s2_confirm,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S3_SUCCEED,
        .name = "Param Config.S3.Succeed",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_param_config_s3_succeed,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_param_config_s3_succeed,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_param_config_s3_succeed,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_PARAM_CONFIG_S4_FAIL,
        .name = "Param Config.S4.Fail",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_param_config_s4_failed,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_param_config_s4_failed,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_param_config_s4_failed,
    },
};

const struct OpenChaoJi_evcc_module c_gbt27930_b_evcc_module_param_config =
    {
        .name = "Param Config",
        .module_id = OPENCHAOJI_GBT27930_B_MODULE_PARAM_CONFIG,
        .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_PARAM_CONFIG,
        .fdc_type = OPENCHAOJI_GBT27930_B_FDC_PARAM_CONFIG_GENERAL,
        .status_array = c_sytem_b_evcc_status_array_param_config,
        .status_array_len = OPENCHAOJI_GBT27930_B_EVCC_STATUS_PARAM_CONFIG_NUM,
};

/* -------------- 授权(RFID) 模块 鲁软 -------------- */
#define OpenChaoJi_gbt27930_b_evcc_prev_auth_rfid_s0_init         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_auth_rfid_s0_init         NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_auth_rfid_s0_init(struct OpenChaoJi_evcc_context * context)
{
    // 初始化
    LOG_STATUS_CHANGE("[%d]Auth RFID S0 init start", context->tag);

    // 创建并打开Tv
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->auth_rfid.Tv, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_AUTH_RFID_TV_EVCC);
    LOG_STATUS_CHANGE("[%d] Tv timer started", context->tag);

    // 进入S1
    LOG_STATUS_CHANGE("[%d]Auth RFID S0 To S1", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S1_NEGOTIATING;
}


#define OpenChaoJi_gbt27930_b_evcc_prev_auth_rfid_s1_nego   NULL
#define OpenChaoJi_gbt27930_b_evcc_post_auth_rfid_s1_nego   NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_auth_rfid_s1_nego(struct OpenChaoJi_evcc_context * context)
{
    // 接收"充电机鉴权参数开始/持续"报文
    if (context->running_data.b->auth_rfid.rfid_param_secc_ok)
    {
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->auth_rfid.T1, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_AUTH_RFID_WAIT_EVCC);
        enum OpenChaoJi_gbt27930_b_VAuthenStatusType app_authen_status;
        app_authen_status = OpenChaoJi_evcc_app_get_auth_status(context); //向app请求车辆等待信息
        if(app_authen_status == OPENCHAOJI_GBT27930_B_EVCC_AUTH_STATUS_WAIT_CONTINUE)//车同意等待
        {
            //发送"车辆鉴权等待报文_继续等待"报文
            LOG_STATUS_CHANGE("[%d]Auth RFID S1 Send Vehicle Auth Wait Waiting", context->tag);
            context->running_data.b->auth_rfid.rfid_wait_evcc.v_authen_status = OPENCHAOJI_GBT27930_B_EVCC_AUTH_STATUS_WAIT_CONTINUE;
            OpenChaoJi_gbt27930_b_evcc_send_normal(context,
                OPENCHAOJI_GBT27930_B_PID_TAG_AUTH_RFID_WAIT_EVCC,
                ((uint8_t *)&context->running_data.b->auth_rfid.rfid_wait_evcc),
                sizeof(context->running_data.b->auth_rfid.rfid_wait_evcc));
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->auth_rfid.T1,OPENCHAOJI_GBT27930_B_PID_TIMEOUT_AUTH_RFID_WAIT_EVCC);

            // 进入S2
            LOG_STATUS_CHANGE("[%d]Auth RFID S1 To S2", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S2_WAIT_SCAN_CARD;
        }
        else if(app_authen_status == OPENCHAOJI_GBT27930_B_EVCC_AUTH_STATUS_WAIT_REJECTED) //不同意等待
        {
            //发送"车辆鉴权等待报文_不同意等待"报文
            LOG_STATUS_CHANGE("[%d]Auth RFID S1 Send Vehicle Auth Wait Not Agree", context->tag);
            context->running_data.b->auth_rfid.rfid_wait_evcc.v_authen_status = OPENCHAOJI_GBT27930_B_EVCC_AUTH_STATUS_WAIT_REJECTED;
            OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_AUTH_RFID_WAIT_EVCC,((uint8_t *)&context->running_data.b->auth_rfid.rfid_wait_evcc),sizeof(context->running_data.b->auth_rfid.rfid_wait_evcc));

            OpenChaoJi_os_soft_timer_start(&context->running_data.b->auth_rfid.T1,OPENCHAOJI_GBT27930_B_PID_TIMEOUT_AUTH_RFID_WAIT_EVCC);

            // 进入S5
            LOG_STATUS_CHANGE("[%d]Auth RFID S1 To S5", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S5_FAIL;
        }
    }

    // Tv定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_rfid.Tv))
    {
        LOG_STATUS_CHANGE("[%d]Auth RFID S1 Tv timer timeout", context->tag);
        LOG_STATUS_CHANGE("[%d]Auth RFID S1 Send Stop Info Auth Timeout", context->tag);

        //发送"中止_鉴权超时"报文
        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_AUTH);

        // 进入S5
        LOG_STATUS_CHANGE("[%d]Auth RFID S1 To S5", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S5_FAIL;
    }

    // 保持S1
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S1_NEGOTIATING;
}


#define OpenChaoJi_gbt27930_b_evcc_prev_auth_rfid_s2_wait   NULL
#define OpenChaoJi_gbt27930_b_evcc_post_auth_rfid_s2_wait   NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_auth_rfid_s2_wait(struct OpenChaoJi_evcc_context * context)
{
    // 接收"接收鉴权结果"报文
    if (context->running_data.b->auth_rfid.rfid_result_secc_ok)
    {
        LOG_STATUS_CHANGE("[%d]Auth RFID S2 Receive Vehicle Auth Result", context->tag);

        //关闭T1
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.T1);
        LOG_STATUS_CHANGE("[%d]Auth RFID S2 T1 timer stopped", context->tag);

        if(context->running_data.b->auth_rfid.rfid_result_secc.authen_result == OPENCHAOJI_GBT27930_B_AUTH_RESULT_SUCCEED)//鉴权成功
        {

            LOG_STATUS_CHANGE("[%d]Auth RFID S2 Authen Result Succeed", context->tag);
            // 进入S3
            LOG_STATUS_CHANGE("[%d]Auth RFID S2 To S3", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S3_PHASE_CONFIRM;
        }
        else //(context->running_data.b->auth_rfid.rfid_result_secc.authen_result == OPENCHAOJI_GBT27930_B_AUTH_RESULT_FAILED) //鉴权失败
        {
            LOG_STATUS_CHANGE("[%d]Auth RFID S2 Authen Result Failed", context->tag);
            // 进入S5
            LOG_STATUS_CHANGE("[%d]Auth RFID S2 To S5", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S5_FAIL;
        }

    }

    // T1定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_rfid.T1))
    {
        LOG_MSG_TIMEOUT("[%d]Auth RFID S2 T1 timer timeout", context->tag);

        //发送"车辆鉴权等待报文_继续等待"报文
        LOG_MSG_TIMEOUT("[%d]Auth RFID S2 Send Vehicle Auth Wait Waiting", context->tag);
		context->running_data.b->auth_rfid.rfid_wait_evcc.v_authen_status = OPENCHAOJI_GBT27930_B_EVCC_AUTH_STATUS_WAIT_CONTINUE;
        OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_AUTH_RFID_WAIT_EVCC,((uint8_t *)&context->running_data.b->auth_rfid.rfid_wait_evcc),sizeof(context->running_data.b->auth_rfid.rfid_wait_evcc));

        //重置t1
        OpenChaoJi_os_soft_timer_reset(&context->running_data.b->auth_rfid.T1);
        LOG_MSG_TIMEOUT("[%d]Auth RFID S2 T1 timer reset", context->tag);
    }

    // Tv定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_rfid.Tv))
    {
        LOG_STATUS_CHANGE("[%d]Auth RFID S2 Tv timer timeout", context->tag);

        //发送"中止_鉴权超时"报文
        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_AUTH);
        LOG_STATUS_CHANGE("[%d]Auth RFID S2 Send Stop Info Auth Timeout", context->tag);

        // 进入S5
        LOG_STATUS_CHANGE("[%d]Auth RFID S2 To S5", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S5_FAIL;
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S2_WAIT_SCAN_CARD;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_auth_rfid_s3_confirm   NULL
#define OpenChaoJi_gbt27930_b_evcc_post_auth_rfid_s3_confirm   NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_auth_rfid_s3_confirm(struct OpenChaoJi_evcc_context * context)
{
    // 接收"充电机阶段信息"报文
    if (context->running_data.b->phase_info_secc_ok)
    {
        LOG_STATUS_CHANGE("[%d]Auth RFID S3 Receive Charge Phase Info", context->tag);

		// 车辆判断是否支持
		if (OpenChaoJi_gbt27930_b_evcc_check_next_phase_info(context))
        {
            // 发送"车辆阶段确认_成功"报文
            LOG_STATUS_CHANGE("[%d]Auth RFID Send Phase Success", context->tag);
            OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED);

            //进入S4
            LOG_STATUS_CHANGE("[%d]Auth RFID S3 To S4", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S4_SUCCEED;
		}
		else
		{
            // 发送"车辆阶段确认_失败"报文
            LOG_STATUS_CHANGE("[%d]Auth RFID Send Phase Fail", context->tag);
            OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_FAILED);

            // 进入S5
            LOG_STATUS_CHANGE("[%d]Auth RFID S3 To S5", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S5_FAIL;
		}

    }

    // Tv定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_rfid.Tv))
    {
        LOG_STATUS_CHANGE("[%d]Auth RFID S3 Tv Timer timeout", context->tag);

        //发送"中止_鉴权超时"报文
        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_AUTH);

        // 进入S5
        LOG_STATUS_CHANGE("[%d]Auth RFID S3 To S5", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S5_FAIL;
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S3_PHASE_CONFIRM;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_auth_rfid_s4_succeed   NULL
#define OpenChaoJi_gbt27930_b_evcc_post_auth_rfid_s4_succeed   NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_auth_rfid_s4_succeed(struct OpenChaoJi_evcc_context * context)
{
    //关闭T1
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.T1);

    // 关闭Tv
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.Tv);
    LOG_STATUS_CHANGE("[%d]Auth RFID S4 Time Stop", context->tag);

    // 进入下一功能模块
    LOG_STATUS_CHANGE("[%d]Auth RFID S4 To Next Fdc", context->tag);
    return  OpenChaoJi_gbt27930_b_evcc_find_next_module_status(context);

}

#define OpenChaoJi_gbt27930_b_evcc_prev_auth_rfid_s5_fail   NULL
#define OpenChaoJi_gbt27930_b_evcc_post_auth_rfid_s5_fail   NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_auth_rfid_s5_fail(struct OpenChaoJi_evcc_context * context)
{
    //关闭T1
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.T1);

    // 关闭Tv
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_rfid.Tv);
    LOG_STATUS_CHANGE("[%d]Auth RFID S5 Exit Stoping fail", context->tag);

    //故障停机
    return  OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_SECC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_SECC_FAILED_AUTH);
}


const struct OpenChaoJi_evcc_module_status c_sytem_b_evcc_status_array_auth_rfid[OPENCHAOJI_GBT27930_B_EVCC_STATUS_AUTH_RFID_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S0_INIT,
        .name = "RFID.S0.Init",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_auth_rfid_s0_init,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_auth_rfid_s0_init,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_auth_rfid_s0_init,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S1_NEGOTIATING,
        .name = "RFID.S1.Negotiating",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_auth_rfid_s1_nego,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_auth_rfid_s1_nego,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_auth_rfid_s1_nego,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S2_WAIT_SCAN_CARD,
        .name = "RFID.S2.WaitScanCard",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_auth_rfid_s2_wait,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_auth_rfid_s2_wait,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_auth_rfid_s2_wait,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S3_PHASE_CONFIRM,
        .name = "RFID.S3.PhaseConfirm",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_auth_rfid_s3_confirm,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_auth_rfid_s3_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_auth_rfid_s3_confirm,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S4_SUCCEED,
        .name = "RFID.S4.Succeed",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_auth_rfid_s4_succeed,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_auth_rfid_s4_succeed,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_auth_rfid_s4_succeed,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_RFID_S5_FAIL,
        .name = "RFID.S5.Fail",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_auth_rfid_s5_fail,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_auth_rfid_s5_fail,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_auth_rfid_s5_fail,
    },
};

const struct OpenChaoJi_evcc_module c_gbt27930_b_evcc_module_auth_rfid =
{
    .name = "Auth RFID",
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_AUTH_RFID,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_AUTH,
    .fdc_type = OPENCHAOJI_GBT27930_B_FDC_AUTH_RFID,
    .status_array = c_sytem_b_evcc_status_array_auth_rfid,
    .status_array_len = OPENCHAOJI_GBT27930_B_EVCC_STATUS_AUTH_RFID_NUM,
};





/* -------------- 授权(EVIN) 模块 鲁软 -------------- */
#define OpenChaoJi_gbt27930_b_evcc_prev_auth_evin_s0_init         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_auth_evin_s0_init         NULL
// 初始化
static int  OpenChaoJi_gbt27930_b_evcc_loop_auth_evin_s0_init(struct OpenChaoJi_evcc_context * context)
{
    // 初始化
    LOG_STATUS_CHANGE("[%d]Auth EVIN S0 Init", context->tag);

    // 打开Tv
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->auth_evin.Tv, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_AUTH_EVIN_TV_EVCC);
    LOG_STATUS_CHANGE("[%d]Auth EVIN S0 Tv Time Start", context->tag);

    // 进入S1
    LOG_STATUS_CHANGE("[%d]Auth EVIN S0 To S1", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S1_NEGOTIATING;
}

// 协商中
#define OpenChaoJi_gbt27930_b_evcc_prev_auth_evin_s1_nego         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_auth_evin_s1_nego         NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_auth_evin_s1_nego(struct OpenChaoJi_evcc_context * context)
{
    // 接收"鉴权请求"报文
    if (context->running_data.b->auth_evin.evin_req_secc_ok)
    {
        LOG_STATUS_CHANGE("[%d]Auth EVIN S1 Recv EVIN Request", context->tag);

        //发送"车辆鉴权参数"报文
        LOG_STATUS_CHANGE("[%d]Auth EVIN S1 Send Vehicle Auth Param", context->tag);
        OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_AUTH_PARAM_EVCC,((uint8_t *)&context->running_data.b->auth_evin.evin_param_evcc),sizeof(context->running_data.b->auth_evin.evin_param_evcc));

        // 进入S2
        LOG_STATUS_CHANGE("[%d]Auth EVIN S1 To S2", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S2_WAIT_RESULT;
    }

    // Tv定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_evin.Tv))
    {
        LOG_STATUS_CHANGE("[%d]Auth EVIN S1 Tv Timeout", context->tag);

        //发送"中止_鉴权超时"报文
        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_AUTH);

        // 进入S5
        LOG_STATUS_CHANGE("[%d]Auth EVIN S1 To S5", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S5_FAIL;
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S1_NEGOTIATING;
}

// 等待协商结果
#define OpenChaoJi_gbt27930_b_evcc_prev_auth_evin_s2_wait         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_auth_evin_s2_wait         NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_auth_evin_s2_wait(struct OpenChaoJi_evcc_context * context)
{
    // 接收"鉴权结果"报文
    if (context->running_data.b->auth_evin.evin_result_secc_ok == 1)
    {
        LOG_STATUS_CHANGE("[%d]Auth EVIN S2 Recv Auth Result", context->tag);
        if(context->running_data.b->auth_evin.evin_result_secc.authen_result == OPENCHAOJI_GBT27930_B_AUTH_RESULT_SUCCEED)//鉴权成功
        {
            // 进入S3
            LOG_STATUS_CHANGE("[%d]Auth EVIN S2 To S3", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S3_PHASE_CONFIRM;
        }
        else if(context->running_data.b->auth_evin.evin_result_secc.authen_result == OPENCHAOJI_GBT27930_B_AUTH_RESULT_FAILED)//鉴权失败
        {
            // 进入S5
            LOG_STATUS_CHANGE("[%d]Auth EVIN S2 To S5", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S5_FAIL;
        }
    }

    // Tv定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_evin.Tv))
    {
        LOG_STATUS_CHANGE("[%d]Auth EVIN S2 Tv Timeout", context->tag);

        //发送"中止_鉴权超时"报文
        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_AUTH);

        // 进入S5
        LOG_STATUS_CHANGE("[%d]Auth EVIN S2 To S5", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S5_FAIL;
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S2_WAIT_RESULT;
}

// 阶段确认
#define OpenChaoJi_gbt27930_b_evcc_prev_auth_evin_s3_confirm         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_auth_evin_s3_confirm         NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_auth_evin_s3_confirm(struct OpenChaoJi_evcc_context * context)
{
    // 接收"充电机阶段信息"报文
    if (context->running_data.b->phase_info_secc_ok == 1)
    {
        LOG_STATUS_CHANGE("[%d]Auth EVIN S3 Recv Charge Phase Info", context->tag);

        // 确认成功
        if (context->running_data.b->phase_ack_evcc.phase_ack == OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED)
        {
            LOG_STATUS_CHANGE("[%d]Auth EVIN S3 Send Vehicle Phase Confirm Succeed", context->tag);

            // 发送"车辆阶段确认_成功"报文
            OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED);

            //进入S4
            LOG_STATUS_CHANGE("[%d]Auth EVIN S3 To S4", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S4_SUCCEED;
        }
        else
        {
            //发送"车辆阶段确认_失败"报文
            OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_FAILED);

            // 进入S5
            LOG_STATUS_CHANGE("[%d]Auth EVIN S3 To S5", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S5_FAIL;
        }

        // Tv定时器到
        if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->auth_evin.Tv))
        {
            LOG_STATUS_CHANGE("[%d]Auth EVIN S3 Tv Timeout", context->tag);

            //发送"中止_鉴权超时"报文
            OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_AUTH);

            // 进入S5
            LOG_STATUS_CHANGE("[%d]Auth EVIN S3 To S5", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S5_FAIL;
        }
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S3_PHASE_CONFIRM;
}

// 成功
#define OpenChaoJi_gbt27930_b_evcc_prev_auth_evin_s4_succeed         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_auth_evin_s4_succeed         NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_auth_evin_s4_succeed(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_CHANGE("[%d]Auth EVIN S4 Succeed", context->tag);

    // 关闭Tv
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_evin.Tv);

    // 进入下一功能模块
    LOG_STATUS_CHANGE("[%d]Auth EVIN S4 Close Tv To Next FDC", context->tag);
    return  OpenChaoJi_gbt27930_b_evcc_find_next_module_status(context);
}

// 完成鉴权
#define OpenChaoJi_gbt27930_b_evcc_prev_auth_evin_s5_fail         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_auth_evin_s5_fail         NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_auth_evin_s5_fail(struct OpenChaoJi_evcc_context * context)
{
    // 关闭Tv
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->auth_evin.Tv);

    LOG_STATUS_CHANGE("[%d]Auth EVIN S5 Close Tv To Exit", context->tag);
    return  OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_FAILED_AUTH);
}

const struct OpenChaoJi_evcc_module_status c_sytem_b_evcc_status_array_auth_evin[OPENCHAOJI_GBT27930_B_EVCC_STATUS_AUTH_EVIN_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S0_INIT,
        .name = "EVIN.S0.Init",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_auth_evin_s0_init,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_auth_evin_s0_init,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_auth_evin_s0_init,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S1_NEGOTIATING,
        .name = "EVIN.S1.Negotiating",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_auth_evin_s1_nego,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_auth_evin_s1_nego,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_auth_evin_s1_nego,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S2_WAIT_RESULT,
        .name = "EVIN.S2.WaitResult",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_auth_evin_s2_wait,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_auth_evin_s2_wait,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_auth_evin_s2_wait,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S3_PHASE_CONFIRM,
        .name = "EVIN.S3.PhaseConfirm",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_auth_evin_s3_confirm,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_auth_evin_s3_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_auth_evin_s3_confirm,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S4_SUCCEED,
        .name = "EVIN.S4.Succeed",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_auth_evin_s4_succeed,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_auth_evin_s4_succeed,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_auth_evin_s4_succeed,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_AUTH_EVIN_S5_FAIL,
        .name = "EVIN.S5.Fail",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_auth_evin_s5_fail,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_auth_evin_s5_fail,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_auth_evin_s5_fail,
    },
};

const struct OpenChaoJi_evcc_module c_gbt27930_b_evcc_module_auth_evin =
{
    .name = "Auth EVIN",
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_AUTH_EVIN,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_AUTH,
    .fdc_type = OPENCHAOJI_GBT27930_B_FDC_AUTH_EVIN,
    .status_array = c_sytem_b_evcc_status_array_auth_evin,
    .status_array_len = OPENCHAOJI_GBT27930_B_EVCC_STATUS_AUTH_EVIN_NUM,
};


/* -------------- 预约 模块 (暂空) -------------- */






/* -------------- 系统自检 模块 领充 -------------- */
/**
 * 自检模块状态定义处理
*/

// 27930 表G.6 S0 初始化
static void OpenChaoJi_gbt27930_b_evcc_prev_selfcheck_s0_init(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_PREV("[%d]Self Check S0 Init Prev -> S0 Init Loop", context->tag);

    LOG_STATUS_PREV("[%d]Self Check S0 Init Prev, Close S2 Switch", context->tag);
    OpenChaoJi_evcc_utility_pilot_b_permit_charge(context->context_pilot, true);
}

#define OpenChaoJi_gbt27930_b_evcc_post_selfcheck_s0_init         NULL
static int  OpenChaoJi_gbt27930_b_evcc_loop_selfcheck_s0_init(struct OpenChaoJi_evcc_context * context)
{
   	//打开Tv,进入Sl
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->self_check.Tv, OPENCHAOJI_GBT27930_B_TIMEOUT_SELFCHECK_PHASE_EVCC);

    LOG_STATUS_CHANGE("[%d]Self Check S0 Init Tv Start", context->tag);
    context->running_data.b->self_check.selfcheck_status_secc_ok = 0;

    LOG_STATUS_CHANGE("[%d]Self Check S0 Init -> S1 Elocked", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S1_ELOCKED;
}

// 27930 表G.6 S1 等待电子锁锁止
static void  OpenChaoJi_gbt27930_b_evcc_prev_selfcheck_s1_elocked(struct OpenChaoJi_evcc_context * context)
{
    // 电子锁上锁
    LOG_STATUS_PREV("[%d]Self Check S1 Elocked Prev, Electronic Locking", context->tag);
    LOG_STATUS_PREV("[%d]Self Check S1 Elocked Prev -> S1 Elocked Loop", context->tag);
    OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle, 1);
}

#define OpenChaoJi_gbt27930_b_evcc_post_selfcheck_s1_elocked      NULL
static int  OpenChaoJi_gbt27930_b_evcc_loop_selfcheck_s1_elocked(struct OpenChaoJi_evcc_context * context)
{
	//接收“充电机自检状态_未检测”报文
	if (context->running_data.b->self_check.selfcheck_status_secc_ok)
	{
		if ((context->running_data.b->self_check.selfcheck_status_secc.check_adhesion_status == OPENCHAOJI_GBT27930_B_CHECK_TYPE_NOT_CHECK)
			&& (context->running_data.b->self_check.selfcheck_status_secc.check_insulation_status == OPENCHAOJI_GBT27930_B_CHECK_TYPE_NOT_CHECK)
			&& (context->running_data.b->self_check.selfcheck_status_secc.check_short_circuit_status == OPENCHAOJI_GBT27930_B_CHECK_TYPE_NOT_CHECK)
			)
		{
			//电子锁锁止
            if (OpenChaoJi_evcc_hal_gbt_b_is_locked(context->hal_handle))
            {
                // 由充电机自检状态报文驱动, 所以每次处理完需要清空标识
                context->running_data.b->self_check.selfcheck_result_secc_ok = 0;

                //电子锁状态报文在别的地方周期发送
                LOG_STATUS_CHANGE("[%d]Self Check S1 Elocked -> S2 Checking", context->tag);
                return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S2_CHECKING;
            }
		}
	}

	//Tv定时器到
	if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->self_check.Tv))
	{
        LOG_STATUS_CHANGE("[%d]Self Check S1 Elocked Tv Timeout", context->tag);
		// 发送“中止_系统自检超时”报文，进入S5

        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_SELFCHECK);
        LOG_STATUS_CHANGE("[%d]Self Check S1 Elocked Send Stop Self Check: Timeout", context->tag);

        LOG_STATUS_CHANGE("[%d]Self Check S1 Elocked -> S5 Fail", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S5_FAIL;
	}

	//保持S1
    LOG_STATUS_LOOP("[%d]Self Check S1 Elocked Keep", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S1_ELOCKED;
}


// 27930 表G.6 S2 系统自检
#define OpenChaoJi_gbt27930_b_evcc_prev_selfcheck_s2_checking      NULL
#define OpenChaoJi_gbt27930_b_evcc_post_selfcheck_s2_checking      NULL
static int  OpenChaoJi_gbt27930_b_evcc_loop_selfcheck_s2_checking(struct OpenChaoJi_evcc_context * context)
{
	//接收“充电机自检状态_未检测”报文
	if (context->running_data.b->self_check.selfcheck_status_secc_ok)
	{
        if (!OpenChaoJi_evcc_hal_gbt_b_is_locked(context->hal_handle))//电子锁未锁止
        {
            //电子锁状态报文在别的地方周期发送
            LOG_STATUS_CHANGE("[%d]Self Check S2 Checking, Not Locked", context->tag);

            // 由充电机自检状态报文驱动, 所以每次处理完需要清空标识
            context->running_data.b->self_check.selfcheck_status_secc_ok = 0;

            LOG_STATUS_CHANGE("[%d]Self Check S2 Checking -> S5 Fail", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S5_FAIL;
        }
	}

	//接收“充电机自检结果”报文
	if (context->running_data.b->self_check.selfcheck_result_secc_ok)
	{
		if ((context->running_data.b->self_check.selfcheck_result_secc.check_adhesion_result == OPENCHAOJI_GBT27930_B_CHECK_RESULT_SUCCEED)
			&& (context->running_data.b->self_check.selfcheck_result_secc.check_short_circuit_result == OPENCHAOJI_GBT27930_B_CHECK_RESULT_SUCCEED)
			&& ((context->running_data.b->self_check.selfcheck_result_secc.check_insulation_result == OPENCHAOJI_GBT27930_B_CHECK_RESULT_SUCCEED)))
		{
			//成功进入S3
            LOG_STATUS_CHANGE("[%d]Self Check S2 Checking -> S3 Confirm", context->tag);
			return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S3_PHASE_CONFIRM;
		}
		else
		{
			//失败进入S5
            LOG_STATUS_CHANGE("[%d]Self Check S2 Checking -> S5 Fail", context->tag);
			return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S5_FAIL;
		}
	}

	//Tv定时器到
	if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->self_check.Tv))
	{
        LOG_STATUS_CHANGE("[%d]Self Check S2 Checking Tv Timeout", context->tag);
		//电子锁状态报文在别的地方周期发送
		OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_SELFCHECK);
        LOG_STATUS_CHANGE("[%d]Self Check S2 Checking Send Stop Self Check: Timeout", context->tag);

        LOG_STATUS_CHANGE("[%d]Self Check S2 Checking -> S5 Fail", context->tag);
		return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S5_FAIL;
    }

	//保持S2
    LOG_STATUS_LOOP("[%d]Self Check S2 Checking Keep", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S2_CHECKING;
}



// 27930 表G.6 S3 阶段确认过程
#define OpenChaoJi_gbt27930_b_evcc_prev_selfcheck_s3_confirm      NULL
#define OpenChaoJi_gbt27930_b_evcc_post_selfcheck_s3_confirm      NULL
static int  OpenChaoJi_gbt27930_b_evcc_loop_selfcheck_s3_confirm(struct OpenChaoJi_evcc_context * context)
{
	//接收“充电机自检状态_未检测”报文
	if (context->running_data.b->self_check.selfcheck_status_secc_ok)
	{
        if (!OpenChaoJi_evcc_hal_gbt_b_is_locked(context->hal_handle))
        {
            LOG_STATUS_CHANGE("[%d]Self Check S3 Confirm, Not Locked", context->tag);

            // 由充电机自检状态报文驱动, 所以每次处理完需要清空标识
            context->running_data.b->self_check.selfcheck_status_secc_ok = 0;

            //电子锁状态报文在别的地方周期发送
            LOG_STATUS_CHANGE("[%d]Self Check S3 Confirm -> S5 Fail", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S5_FAIL;
        }
	}

	// 接收"车辆阶段确认"报文
	if (context->running_data.b->phase_info_secc_ok)
	{
        // 车辆判断是否支持
        if (OpenChaoJi_gbt27930_b_evcc_check_next_phase_info(context))
        {
            // 发送"车辆阶段确认_成功"报文
            OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED);
            LOG_STATUS_CHANGE("[%d]Self Check S3 Confirmg Send Phase Confirm Success", context->tag);

            //进入S3
            LOG_STATUS_CHANGE("[%d]Self Check S3 Confirm -> S4 Success", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S4_SUCCEED;
        }
        else
        {
            // 发送"车辆阶段确认_失败"报文
            OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_FAILED);
            LOG_STATUS_CHANGE("[%d]Self Check S3 Confirmg Send Phase Confirm Fail", context->tag);

            //进入S5
            LOG_STATUS_CHANGE("[%d]Self Check S3 Confirm -> S5 Fail", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S5_FAIL;
        }
    }

    //Tv定时器到
	if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->self_check.Tv))
	{
        LOG_STATUS_CHANGE("[%d]Self Check S3 Confirmg Tv Timeout", context->tag);

		//电子锁状态报文在别的地方周期发送
		OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_SELFCHECK);
        LOG_STATUS_CHANGE("[%d]Self Check S3 Confirm Send Stop Self Check: Timeout", context->tag);

        LOG_STATUS_CHANGE("[%d]Self Check S3 Confirm -> S5 Fail", context->tag);
		return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S5_FAIL;
    }

	//保持s3
    LOG_STATUS_LOOP("[%d]Self Check S3 Confirm Keep", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S3_PHASE_CONFIRM;
}


// 27930 表G.6 S4 成功
#define OpenChaoJi_gbt27930_b_evcc_prev_selfcheck_s4_succeed      NULL
#define OpenChaoJi_gbt27930_b_evcc_post_selfcheck_s4_succeed      NULL
static int  OpenChaoJi_gbt27930_b_evcc_loop_selfcheck_s4_succeed(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_CHANGE("[%d]Self Check S4 Success", context->tag);

	//关闭Tv定时器，进入下一个功能模块FDC
	OpenChaoJi_os_soft_timer_stop(&context->running_data.b->self_check.Tv);
    LOG_STATUS_CHANGE("[%d]Self Check S4 Tv Stop", context->tag);

    // 根据功能协商结果进入下一功能模块FDC
    return OpenChaoJi_gbt27930_b_evcc_find_next_module_status(context);
}


// 27930 表G.5 S5 失败
#define OpenChaoJi_gbt27930_b_evcc_prev_selfcheck_s5_failed      NULL
#define OpenChaoJi_gbt27930_b_evcc_post_selfcheck_s5_failed      NULL
static int  OpenChaoJi_gbt27930_b_evcc_loop_selfcheck_s5_failed(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_CHANGE("[%d]Self Check S5 Fail", context->tag);

	//关闭Tv定时器，如果功能协商结果中“服务统计”功能模块协商成功，则在阶段确认后进入服务统计功能模块FDC,否则退出充电过程
	OpenChaoJi_os_soft_timer_stop(&context->running_data.b->self_check.Tv);
    LOG_STATUS_CHANGE("[%d]Self Check S5 Tv Stop", context->tag);

    // 退出充电过程
    return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_FAILED_SELFCHECK);
}


const struct OpenChaoJi_evcc_module_status c_sytem_b_evcc_status_array_self_check[OPENCHAOJI_GBT27930_B_EVCC_STATUS_SELF_CHECK_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S0_INIT,
        .name = "SelfCheck.S0.Init",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_selfcheck_s0_init,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_selfcheck_s0_init,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_selfcheck_s0_init,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S1_ELOCKED,
        .name = "SelfCheck.S1.Elocked",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_selfcheck_s1_elocked,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_selfcheck_s1_elocked,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_selfcheck_s1_elocked,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S2_CHECKING,
        .name = "SelfCheck.S2.Checking",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_selfcheck_s2_checking,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_selfcheck_s2_checking,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_selfcheck_s2_checking,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S3_PHASE_CONFIRM,
        .name = "SelfCheck.S3.PhaseConfirm",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_selfcheck_s3_confirm,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_selfcheck_s3_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_selfcheck_s3_confirm,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S4_SUCCEED,
        .name = "SelfCheck.S4.Succeed",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_selfcheck_s4_succeed,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_selfcheck_s4_succeed,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_selfcheck_s4_succeed,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S5_FAIL,
        .name = "SelfCheck.S5.Fail",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_selfcheck_s5_failed,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_selfcheck_s5_failed,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_selfcheck_s5_failed,
    },
};

const struct OpenChaoJi_evcc_module c_gbt27930_b_evcc_module_self_check =
{
    .name = "SelfCheck",
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_SELFCHECK,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_SELFCHECK,
    .fdc_type = OPENCHAOJI_GBT27930_B_FDC_SELFCHECK_GENERAL,
    .status_array = c_sytem_b_evcc_status_array_self_check,
    .status_array_len = OPENCHAOJI_GBT27930_B_EVCC_STATUS_SELF_CHECK_NUM,
};


/* -------------- 预充及能量传输 模块 鲁软 -------------- */
/* 充电模式能量传输 FDC=1 */
#define OpenChaoJi_gbt27930_b_evcc_prev_charging_s0_init         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_charging_s0_init         NULL
// 初始化
static int  OpenChaoJi_gbt27930_b_evcc_loop_charging_s0_init(struct OpenChaoJi_evcc_context * context)
{
    // 初始化
    LOG_STATUS_CHANGE("[%d]Energy Charge S0 Init", context->tag);
    context->running_data.b->charging.charging_ready_secc_ok = 0;
    context->running_data.b->charging.charging_ability_secc_ok = 0;
    context->running_data.b->charging.charging_pause_secc_ok = 0;
    context->running_data.b->charging.charging_requirement_change = 0;

    //打开tv
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.Tv, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_TV_EVCC);
    LOG_STATUS_CHANGE("[%d]Energy Charge S0 Init TV Start", context->tag);

    // 进入S1
    LOG_STATUS_CHANGE("[%d]Energy Charge S0 Init Enter S1", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S1_CHARGER_STATUS_CONFIRM;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_charging_s1_confirm         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_charging_s1_confirm         NULL
// 由于27930未定义停止流程, 故H2,H3, H4等异常处理流程均不能按照状态转换表跳转到S5/S7状态, 改为跳转到Stopping_fail阶段
// Stopping_fail阶段会在执行停止流程后, 根据功能协商结果确认是否进入服务统计或直接结束
// 所以H2/H3/H4等在此处仅需释放本地定时器等资源后跳转Stopping_fail即可

static int OpenChaoJi_gbt27930_b_evcc_loop_charging_H1(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_CHANGE("[%d]Energy Charge H1", context->tag);

    // 关闭定时器
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tv);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_T2_EVCC);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T3);

    // 发送"中止_预充超时"报文
    return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_ENERGY);
}

static int OpenChaoJi_gbt27930_b_evcc_loop_charging_H2(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_CHANGE("[%d]Energy Charge H2", context->tag);

    // 关闭定时器
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tv);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_T2_EVCC);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T3);

    // 发送"中止_车辆正常中止"报文
    return OpenChaoJi_gbt27930_b_evcc_stop_normal(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TERM_NORMAL);
}
static int OpenChaoJi_gbt27930_b_evcc_loop_charging_H3(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_CHANGE("[%d]Energy Charge H3", context->tag);

    // 关闭定时器
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tv);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_T2_EVCC);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T3);

    // 桩端停止, EVCC无需发送停止报文
    return OpenChaoJi_gbt27930_b_evcc_stop_normal(context, 0, 0);
}
static int  OpenChaoJi_gbt27930_b_evcc_loop_charging_s1_confirm(struct OpenChaoJi_evcc_context * context)
{
    // 接收"充电机就绪状态"报文
    if (context->running_data.b->charging.charging_ready_secc_ok)
    {
        LOG_DATA_NORMAL("[%d]Energy Charge S1 Confirm Receive Energy Charger Ready Secc", context->tag);
        if(context->running_data.b->charging.charging_ready_secc.ready_status == OPENCHAOJI_GBT27930_B_READY_TYPE_NOT_READY)//充电机未就绪
        {
            LOG_STATUS_CHANGE("[%d]Energy Charge S1 Charger Not Ready", context->tag);

            //发送"车辆就绪状态_未就绪"报文
            context->running_data.b->charging.charging_ready_evcc.ready_status = OPENCHAOJI_GBT27930_B_READY_TYPE_NOT_READY;
            context->running_data.b->charging.charging_ready_evcc.voltage = OpenChaoJi_evcc_hal_get_measured_voltage(context->hal_handle);

            LOG_STATUS_CHANGE("[%d]Energy Charge S1 Send Vehicle Not Ready Evcc", context->tag);
            OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_READY_EVCC,((uint8_t *)&context->running_data.b->charging.charging_ready_evcc), sizeof(context->running_data.b->charging.charging_ready_evcc)) ;

            //闭合车辆断开装置
            OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 1);

            // 进入S2
            LOG_STATUS_CHANGE("[%d]Energy Charge S1 To S2", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S2_VEHICLE_NOT_READY;
        }
    }

    // Tv定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.Tv))
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 EVCC SIDE Timeout Stop", context->tag);
        return OpenChaoJi_gbt27930_b_evcc_loop_charging_H1(context);
    }

    if (!context->app_permit_charge)//车辆主动中止
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 EVCC SIDE Active Stop", context->tag);
        return OpenChaoJi_gbt27930_b_evcc_loop_charging_H2(context);
    }

    if (context->running_data.b->stop_info_secc_ok)//接收"充电机中止"报文
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 SECC SIDE Active Stop", context->tag);
        return OpenChaoJi_gbt27930_b_evcc_loop_charging_H3(context);
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S1_CHARGER_STATUS_CONFIRM;
}

static void OpenChaoJi_gbt27930_b_evcc_prev_charging_s2_pre(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_PREV("[%d] battery prepare for charging", context->tag);

    OpenChaoJi_evcc_hal_battery_prepare(context->hal_handle);
}
#define OpenChaoJi_gbt27930_b_evcc_post_charging_s2_pre         NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_charging_s2_pre(struct OpenChaoJi_evcc_context * context)
{
    // 接收"充电机就绪状态"报文
    if (context->running_data.b->charging.charging_ready_secc_ok)
    {
        LOG_DEBUG("[%d]Energy Charge S2 Receive Charger Ready", context->tag);

        //发送"车辆就绪状态_未就绪"报文
        LOG_DEBUG("[%d]Energy Charge S2 Send Vehicle Not Ready", context->tag);
        context->running_data.b->charging.charging_ready_evcc.voltage = OpenChaoJi_evcc_hal_get_measured_voltage(context->hal_handle);
        OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_READY_EVCC, (uint8_t *)&context->running_data.b->charging.charging_ready_evcc, sizeof(context->running_data.b->charging.charging_ready_evcc));
    }

    // Tv定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.Tv))
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 EVCC SIDE Timeout Stop", context->tag);
        return OpenChaoJi_gbt27930_b_evcc_loop_charging_H1(context);
    }

    // 检查电池是否投入成功
    context->running_data.b->charging.charging_input_battery_success = OpenChaoJi_evcc_hal_battery_is_ready(context->hal_handle);
    if (context->running_data.b->charging.charging_input_battery_success)
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge Battery Ready", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S3_VEHICLE_READY;
    }

    if (!context->app_permit_charge)//车辆主动中止
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S1 EVCC SIDE Active Stop", context->tag);
        return OpenChaoJi_gbt27930_b_evcc_loop_charging_H2(context);
    }

    if (context->running_data.b->stop_info_secc_ok)//接收"充电机中止"报文
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S2 Receive Charger Stop", context->tag);
        return OpenChaoJi_gbt27930_b_evcc_loop_charging_H3(context);
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S2_VEHICLE_NOT_READY;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_charging_s3_ready         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_charging_s3_ready         NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_charging_s3_ready(struct OpenChaoJi_evcc_context * context)
{
    // 接收"充电机就绪状态"报文
    if (context->running_data.b->charging.charging_ready_secc_ok)
    {
        LOG_DATA_NORMAL("[%d]Energy Charge S3 Receive Charger Ready", context->tag);

        //充电机就绪
        if (context->running_data.b->charging.charging_ready_secc.ready_status == OPENCHAOJI_GBT27930_B_READY_TYPE_READY)
        {
            // 向车查询车辆充电需求
            struct OpenChaoJi_evcc_gbt27930_charging_requirement_parameter charging_requirement_evcc;
            OpenChaoJi_evcc_app_get_charging_requirement(context, &charging_requirement_evcc);
            context->running_data.b->charging.charging_requirement_evcc.voltage = charging_requirement_evcc.voltage;
            context->running_data.b->charging.charging_requirement_evcc.current = charging_requirement_evcc.current;
            context->running_data.b->charging.charging_requirement_evcc.charge_mode = charging_requirement_evcc.charge_mode;

            //发送"车辆充电需求"报文
            LOG_STATUS_CHANGE("[%d]Energy Charge S3 Send Vehicle Charge Requirement", context->tag);
            OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_REQUIREMENT_EVCC,((uint8_t *)&context->running_data.b->charging.charging_requirement_evcc),sizeof(context->running_data.b->charging.charging_requirement_evcc));

            //发送"车辆充电基本信息"报文
            LOG_STATUS_CHANGE("[%d]Energy Charge S3 Send Vehicle Charge Info Basic", context->tag);
			context->running_data.b->charging.charging_info_basic_evcc.soc = OpenChaoJi_evcc_hal_get_batt_soc(context->hal_handle);
			context->running_data.b->charging.charging_info_basic_evcc.left_time = OpenChaoJi_evcc_hal_get_expected_time(context->hal_handle);
            OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_INFO_BASIC_EVCC,((uint8_t *)&context->running_data.b->charging.charging_info_basic_evcc),sizeof(context->running_data.b->charging.charging_info_basic_evcc));

            //发送"车辆电池基本信息"报文 协议建议在就绪阶段加入车辆电池基本信息
            LOG_STATUS_CHANGE("[%d]Energy Charge S3 Send Vehicle Charge Info Basic", context->tag);
			context->running_data.b->charging.charging_info_battery_evcc.voltage_max = OpenChaoJi_evcc_hal_get_max_cellvolt(context->hal_handle).voltage;
			context->running_data.b->charging.charging_info_battery_evcc.voltage_min = OpenChaoJi_evcc_hal_get_min_cellvolt(context->hal_handle).voltage;
			context->running_data.b->charging.charging_info_battery_evcc.temperature_max = OpenChaoJi_evcc_hal_get_max_tempera(context->hal_handle).tempera;
			context->running_data.b->charging.charging_info_battery_evcc.temperature_min = OpenChaoJi_evcc_hal_get_min_tempera(context->hal_handle).tempera;
            OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_INFO_BATTERY_EVCC,((uint8_t *)&context->running_data.b->charging.charging_info_battery_evcc),sizeof(context->running_data.b->charging.charging_info_battery_evcc));

            // 关闭TV
            LOG_STATUS_CHANGE("[%d]Energy Charge S3 Close TV", context->tag);
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tv);

            // 开启T1 T3 T4
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T1, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_INFO_BASIC_EVCC);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_REQUIREMENT_EVCC);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_INFO_BATTERY_EVCC);

            // 进入 S4
            LOG_STATUS_CHANGE("[%d]Energy Charge S3 To S4", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S4_ENERGY_TRANSFER;
        }//if(context->running_data.b->charging.charging_ready_secc.ready_status == OPENCHAOJI_GBT27930_B_READY_TYPE_NOT_READY)//未就绪
        else
        {
            //充电机未就绪
            //发送"车辆就绪状态_就绪"报文
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_REQUIREMENT_EVCC);

            LOG_DATA_NORMAL("[%d]Energy Charge S3 Send Vehicle Ready Status Ready", context->tag);
            context->running_data.b->charging.charging_ready_evcc.voltage = OpenChaoJi_evcc_hal_get_measured_voltage(context->hal_handle);
            context->running_data.b->charging.charging_ready_evcc.ready_status = OPENCHAOJI_GBT27930_B_READY_TYPE_READY;
            OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_READY_EVCC,((uint8_t *)&context->running_data.b->charging.charging_ready_evcc),sizeof(context->running_data.b->charging.charging_ready_evcc));

            // 规范中要求收到SECC的Ready报文后应答, 而不是每次应答, 故这里需要清空SECC_Ready接收标识
            context->running_data.b->charging.charging_ready_secc_ok = 0;
        }
    }

    // Tv定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.Tv))
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S3 Tv Timeout", context->tag);
        return OpenChaoJi_gbt27930_b_evcc_loop_charging_H1(context);
    }

    if (!context->app_permit_charge)//车辆主动中止
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S3 Vehicle Active Stop", context->tag);
        return OpenChaoJi_gbt27930_b_evcc_loop_charging_H2(context);
    }

    if (context->running_data.b->stop_info_secc_ok)//接收"充电机中止"报文
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S3 Receive Charger Stop", context->tag);
        return OpenChaoJi_gbt27930_b_evcc_loop_charging_H3(context);
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S3_VEHICLE_READY;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_charging_s4_transfer         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_charging_s4_transfer         NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_charging_s4_transfer(struct OpenChaoJi_evcc_context * context)
{
   // 接收"充电机动态输出能力"报文
    if (context->running_data.b->charging.charging_ability_secc_ok)
    {
        LOG_DATA_NORMAL("[%d]Energy Charge S4 Receive Charger Dynamic Output Capacity", context->tag);

        // 向车查询车辆充电需求
        struct OpenChaoJi_evcc_gbt27930_charging_requirement_parameter charging_requirement_evcc;
        OpenChaoJi_evcc_app_get_charging_requirement(context, &charging_requirement_evcc);
        context->running_data.b->charging.charging_requirement_evcc.voltage = charging_requirement_evcc.voltage;
        context->running_data.b->charging.charging_requirement_evcc.current = charging_requirement_evcc.current;
        context->running_data.b->charging.charging_requirement_evcc.charge_mode = charging_requirement_evcc.charge_mode;

        // app根据电池自行判断 根据实际情况调节充电需求
        if(context->running_data.b->charging.charging_requirement_evcc.current != context->running_data.b->charging.charging_ability_secc.current)
        {
            context->running_data.b->charging.charging_requirement_change = 1;
            context->running_data.b->charging.charging_ability_secc_ok = 0;
        }
        // 保持S4
    }

    // T3定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.T3)
        || context->running_data.b->charging.charging_requirement_change == 1)
    {
        context->running_data.b->charging.charging_requirement_change = 0;

        //发送"车辆充电需求"报文
        LOG_DATA_NORMAL("[%d]Energy Charge S4 Send Vehicle Energy Charge Requirement", context->tag);
        OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_REQUIREMENT_EVCC,((uint8_t *)&context->running_data.b->charging.charging_requirement_evcc),sizeof(context->running_data.b->charging.charging_requirement_evcc));

        OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_REQUIREMENT_EVCC);
    }

    // T1定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.T1))
    {
        LOG_DATA_NORMAL("[%d]Energy Charge S4 T1 Timeout", context->tag);

        //发送"车辆基本信息"报文
        LOG_DATA_NORMAL("[%d]Energy Charge S4 Send Vehicle Basic Info", context->tag);
        context->running_data.b->charging.charging_info_basic_evcc.soc = OpenChaoJi_evcc_hal_get_batt_soc(context->hal_handle);
        context->running_data.b->charging.charging_info_basic_evcc.left_time = OpenChaoJi_evcc_hal_get_expected_time(context->hal_handle);
        OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_INFO_BASIC_EVCC,((uint8_t *)&context->running_data.b->charging.charging_info_basic_evcc),sizeof(context->running_data.b->charging.charging_info_basic_evcc));

        OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T1, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_INFO_BASIC_EVCC);
    }

    // T4定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.T4))
    {
        LOG_DATA_NORMAL("[%d]Energy Charge S4 T4 Timeout", context->tag);

        //发送"车辆电池基本信息"报文
        OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_INFO_BATTERY_EVCC,((uint8_t *)&context->running_data.b->charging.charging_info_battery_evcc),sizeof(context->running_data.b->charging.charging_info_battery_evcc));
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->charging.T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_CHARGING_INFO_BATTERY_EVCC);
    }

    // //TODO:车辆主动暂停充电
    // if(context->running_data.b->charging.charging_active_charge_paused == 1)//暂停
    // {
    //     LOG_NOTICE("[%d]Energy Charge S4 Vehicle Active Pause", context->tag);
    //     //发送"车辆暂停充电_暂停"报文
    //     context->running_data.b->charging.charging_pause_evcc.pause_status = 0;
    //     if(OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_PAUSE_EVCC,((uint8_t *)&context->running_data.b->charging.charging_pause_evcc),sizeof(context->running_data.b->charging.charging_pause_evcc)) == 0)
    //         return OpenChaoJi_gbt27930_b_evcc_stop_failed(context);
    //     // 等待充电机暂停能量传输
    //     // 保持S4
    //     LOG_INFO("[%d]Energy Charge S4 Loop", context->tag);
    //     return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S4_ENERGY_TRANSFER;
    // }else if(context->running_data.b->charging.charging_active_charge_paused == 0)//恢复
    // {
    //     //发送"车辆暂停充电_恢复"报文
    //     LOG_NOTICE("[%d]Energy Charge S4 Vehicle Active Resume", context->tag);

    //     context->running_data.b->charging.charging_pause_evcc.pause_status = 1;
    //     if(OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_CHARGING_PAUSE_EVCC,((uint8_t *)&context->running_data.b->charging.charging_pause_evcc),sizeof(context->running_data.b->charging.charging_pause_evcc)) == 0)
    //         return OpenChaoJi_gbt27930_b_evcc_stop_failed(context);
    //     // 等待充电机恢复能量传输
    //     // 保持S4
    //     LOG_INFO("[%d]Energy Charge S4 Loop", context->tag);
    //     return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S4_ENERGY_TRANSFER;
    // }

    if (!context->app_permit_charge)//车辆主动中止
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S4 Vehicle Active Stop", context->tag);
        return OpenChaoJi_gbt27930_b_evcc_loop_charging_H2(context);
    }

    if (context->running_data.b->stop_info_secc_ok)//接收"充电机中止"报文
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S4 Receive Stop From SECC", context->tag);
        return OpenChaoJi_gbt27930_b_evcc_loop_charging_H3(context);
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S4_ENERGY_TRANSFER;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_charging_s5_confirm         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_charging_s5_confirm         NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_charging_s5_confirm(struct OpenChaoJi_evcc_context * context)
{
    // 接收"充电机阶段信息"报文
    if (context->running_data.b->phase_info_secc_ok)
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S5 Receive Phase Info From SECC", context->tag);

        // 确认成功
        if (context->running_data.b->phase_ack_evcc.phase_ack == OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED)
        {
            // 发送"车辆阶段确认_成功"报文
            OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED);

            //进入S6
            LOG_STATUS_CHANGE("[%d]Energy Charge S5 To S6", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S6_FINISH;
        }
        else
        {
            //发送"车辆阶段确认_失败"报文
            //LOG_STATUS_CHANGE("[%d]Energy Charge S5 Send Vehicle Phase Confirm Failed", context->tag);

            // 发送"车辆阶段确认_失败"报文
            //OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_FAILED);

            // 进入S7
            LOG_STATUS_CHANGE("[%d]Energy Charge S5 To stop failed", context->tag); //故障停机
            return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_FAILED_PHASE);
        }
    }

    // T2定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.T2))
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S5 T2 Timeout", context->tag);

        // 发送"中止_阶段确认超时"报文
        //OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_ENERGY);

        // 进入S7
        LOG_STATUS_CHANGE("[%d]Energy Charge S5 To Stop fail", context->tag);
        return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_ENERGY);
    }

    // T2定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->charging.T2))
    {
        LOG_STATUS_CHANGE("[%d]Energy Charge S5 T2 Timeout", context->tag);

        // 发送"中止_阶段确认超时"报文
        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_SECC_TIMEOUT_ENERGY);

        // 进入S7
        LOG_STATUS_CHANGE("[%d]Energy Charge S5 To Stop fail", context->tag);
        return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_FAILED, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_FAILED_ENERGY);
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S5_PHASE_CONFIRM;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_charging_s6_finish         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_charging_s6_finish         NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_charging_s6_finish(struct OpenChaoJi_evcc_context * context)
{
    // 关闭Tv T1-T4
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tv);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T2);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T3);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T4);

    LOG_STATUS_CHANGE("[%d]Energy Charge S6 To Next FDC", context->tag);
    // 根据功能协商结果进入下一功能模块FDC
    return OpenChaoJi_gbt27930_b_evcc_find_next_module_status(context);
}

#define OpenChaoJi_gbt27930_b_evcc_prev_charging_s7_exit         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_charging_s7_exit         NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_charging_s7_exit(struct OpenChaoJi_evcc_context * context)
{
    // 关闭Tv T1-T4
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.Tv);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T1);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T2);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T3);
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->charging.T4);

    LOG_STATUS_CHANGE("[%d]Energy Charge S7 Exit Normal", context->tag);

    return  OpenChaoJi_gbt27930_b_evcc_stop_normal(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TERM_NORMAL);//正常停机
}

const struct OpenChaoJi_evcc_module_status c_sytem_b_evcc_status_array_charging[OPENCHAOJI_GBT27930_B_EVCC_STATUS_SUPPLY_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S0_INIT,
        .name = "Charging.S0.Init",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_charging_s0_init,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_charging_s0_init,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_charging_s0_init,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S1_CHARGER_STATUS_CONFIRM,
        .name = "Charging.S1.Confirm",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_charging_s1_confirm,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_charging_s1_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_charging_s1_confirm,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S2_VEHICLE_NOT_READY,
        .name = "Charging.S2.NotReady",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_charging_s2_pre,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_charging_s2_pre,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_charging_s2_pre,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S3_VEHICLE_READY,
        .name = "Charging.S3.Ready",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_charging_s3_ready,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_charging_s3_ready,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_charging_s3_ready,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S4_ENERGY_TRANSFER,
        .name = "Charging.S4.Transfer",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_charging_s4_transfer,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_charging_s4_transfer,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_charging_s4_transfer,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S5_PHASE_CONFIRM,
        .name = "Charging.S5.Confirm",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_charging_s5_confirm,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_charging_s5_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_charging_s5_confirm,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S6_FINISH,
        .name = "Charging.S6.Finish",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_charging_s6_finish,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_charging_s6_finish,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_charging_s6_finish,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S7_EXIT_CHARGING,
        .name = "Charging.S7.Exit",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_charging_s7_exit,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_charging_s7_exit,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_charging_s7_exit,
    },

};

const struct OpenChaoJi_evcc_module c_gbt27930_b_evcc_module_charging =
{
    .name = "Charging",
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_CHARGING,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_ENERGY,
    .fdc_type = OPENCHAOJI_GBT27930_B_FDC_CHARGING,
    .status_array = c_sytem_b_evcc_status_array_charging,
    .status_array_len = OPENCHAOJI_GBT27930_B_EVCC_STATUS_SUPPLY_NUM,
};

/* -------------- 服务统计停止中 模块 鲁软 -------------- */
//#define OpenChaoJi_gbt27930_b_evcc_prev_statistics_stoping_s0_normal         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_statistics_stoping_s0_normal         NULL
void OpenChaoJi_gbt27930_b_evcc_prev_statistics_stoping_s0_normal(struct OpenChaoJi_evcc_context * context)
{
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_Tv, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_TV_EVCC);
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T1, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T1_EVCC);
    context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state = 0x00;

    LOG_STATUS_CHANGE("[%d]Stopping S0, wait C1C2 opened &current<=5A", context->tag);
}

static int  OpenChaoJi_gbt27930_b_evcc_loop_statistics_stoping_s0_normal(struct OpenChaoJi_evcc_context * context)
{
    if (context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state == 0x00)
    {
        OpenChaoJi_evcc_hal_sampling_value(context->hal_handle, &context->running_data.b->charging.charging_evcc_hal_samp);
        LOG_DATA_NORMAL("[%d]sample_current:%d c1:%d c2:%d", context->tag
            , context->running_data.b->charging.charging_evcc_hal_samp.current
            , context->running_data.b->relay_status_secc.contact_c1
            , context->running_data.b->relay_status_secc.contact_c2);

        // 公共报文发送C1C2解析状态为断开 并且电流小于5A
        if((context->running_data.b->relay_status_secc.contact_c1 == OPENCHAOJI_GBT27930_B_CONTACT_STATUS_OPENED)
            && (context->running_data.b->relay_status_secc.contact_c2 == OPENCHAOJI_GBT27930_B_CONTACT_STATUS_OPENED)
            && (context->running_data.b->charging.charging_evcc_hal_samp.current < 50))
        {
            LOG_STATUS_CHANGE("[%d]sample_current<=5A C1C2 Opened", context->tag);
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T1);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T2_EVCC);

            //可进行 C5C6黏连监测
            //断开C5C6
            OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);

            context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state = 0x01;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_normol_evcc_state 0x00->0x01", context->tag);
        }
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state == 0x01)
    {
        //等待接触器断开  断开S2
        if(OpenChaoJi_evcc_hal_get_status_dc_relay(context->hal_handle) == 0)
        {
            LOG_STATUS_CHANGE("[%d]C5C6 opened", context->tag);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T2);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T3_EVCC);

            OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle, 0);

            context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state = 0x02;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_normol_evcc_state 0x01->0x02", context->tag);
        }
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state == 0x02)
    {
        // 等待分S2成功 且 监测点2电压  在2.34v 10.8v 8.73v 区段
        enum OpenChaoJi_pilot_status_gbt18487_b status_b = OpenChaoJi_evcc_utility_pilot_status_b(context->context_pilot);
        if ((!OpenChaoJi_evcc_hal_gbt_b_is_closed_s2(context->hal_handle))
            && ((status_b == OPENCHAOJI_PILOT_STATUS_GBT18487_B_B) || (status_b == OPENCHAOJI_PILOT_STATUS_GBT18487_B_C) || (status_b == OPENCHAOJI_PILOT_STATUS_GBT18487_B_Ap)))
        {
            LOG_STATUS_CHANGE("[%d]S2 opened", context->tag);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T3);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T4_EVCC);
            context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state = 0x03;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_normol_evcc_state 0x02->0x03", context->tag);
        }
        else
        {
            OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle, 0);
        }
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state == 0x03)
    {
        //等待电压下降OpenChaoJi_evcc_hal_sampling_value  < 60 V 外侧电压
        OpenChaoJi_evcc_hal_sampling_value(context->hal_handle, &context->running_data.b->charging.charging_evcc_hal_samp);
        LOG_DATA_NORMAL("[%d]voltage_out:%d", context->tag, context->running_data.b->charging.charging_evcc_hal_samp.voltage_out);

        if(context->running_data.b->charging.charging_evcc_hal_samp.voltage_out < 600)
        {
            LOG_STATUS_CHANGE("[%d]voltage_out<60V, Unlock", context->tag);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T4);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T5, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T5_EVCC);

            OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle, 0);
            context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state = 0x04;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_normol_evcc_state 0x03->0x04", context->tag);
        }
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state == 0x04)
    {
        //等待分电子锁  获取电子锁状态
        if(OpenChaoJi_evcc_hal_gbt_b_is_locked(context->hal_handle) == 0)
        {
            LOG_STATUS_CHANGE("[%d]Unlocked", context->tag);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T5);

            OpenChaoJi_evcc_hal_gbt_b_close_s2p(context->hal_handle, 0);

            context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state = 0x05;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_normol_evcc_state 0x04->0x05", context->tag);
        }
    }


    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Normal_Tv))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_Tv);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T1);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T2);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T3);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T4);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T5);

        OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_close_s2p(context->hal_handle, 0);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_normol_evcc_state [%02x]->0x05 ,normal stopping timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state = 0x05;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Normal_T1))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T1);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T2_EVCC);

        // 可进行 C5C6黏连监测
        // 断开C5C6
        OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_normol_evcc_state [%02x]->0x01 because T1 timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state = 0x01;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Normal_T2))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T2);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T3_EVCC);

        //断开S2
        OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle, 0);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_normol_evcc_state [%02x]->0x02 because T2 C5/C6 disconnect timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state = 0x02;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Normal_T3))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T3);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T4_EVCC);

        OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle, 0);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_normol_evcc_state [%02x]->0x03 because T3 S2 disconnect timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state = 0x03;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Normal_T4))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T4);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Normal_T5, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_NORMAL_T5_EVCC);

        OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_close_s2p(context->hal_handle, 0);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_normol_evcc_state [%02x]->0x04 because T4 Vent timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state = 0x04;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Normal_T5))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T5);
        LOG_NOTICE("[%d] statistics_stoping_normol_evcc_state [%02x]->0x05 T5 The electronic lock unlock timed out", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state = 0x05;
    }

    if(context->running_data.b->statistics_stoping.statistics_stoping_normol_evcc_state == 0x05)
    {
        OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_close_s2p(context->hal_handle, 0);

        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_Tv);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T1);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T2);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T3);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T4);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Normal_T5);

        // 服务统计协商成功
        if (context->running_data.b->func_nego.func_support_evcc.fdc_statistics == OPENCHAOJI_GBT27930_B_FDC_STATISTICS)
        {
            // 发送“车辆阶段确认信息”报文
            //OpenChaoJi_gbt27930_b_evcc_next_phase_info_send(context);

            // 打开T0
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.State_Tv, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_STATE_TV_EVCC);

            LOG_STATUS_CHANGE("[%d]Stoping Charge S0 To S3", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S3_PHASE_CONFIRM;
        }
        else
        {
            // 退出流程
            LOG_STATUS_CHANGE("[%d]Stoping Charge S0 Exit", context->tag);

            // 根据功能协商结果进入下一功能模块FDC
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S0_FINISHING;
        }
    }

    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S0_NORMAL;
}

//#define OpenChaoJi_gbt27930_b_evcc_prev_statistics_stoping_s1_fault         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_statistics_stoping_s1_fault         NULL

void  OpenChaoJi_gbt27930_b_evcc_prev_statistics_stoping_s1_fault(struct OpenChaoJi_evcc_context * context)
{

    OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_Tv, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_TV_EVCC);
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T1, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T1_EVCC);
    context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state = 0x00;
}

static int  OpenChaoJi_gbt27930_b_evcc_loop_statistics_stoping_s1_fault(struct OpenChaoJi_evcc_context * context)
{
    if(context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state == 0x00)
    {
        OpenChaoJi_evcc_hal_sampling_value(context->hal_handle, &context->running_data.b->charging.charging_evcc_hal_samp);
        LOG_DATA_NORMAL("[%d]sample_current:%d c1:%d c2:%d", context->tag
            , context->running_data.b->charging.charging_evcc_hal_samp.current
            , context->running_data.b->relay_status_secc.contact_c1
            , context->running_data.b->relay_status_secc.contact_c2);

        // 公共报文发送C1C2解析状态为断开 并且电流小于5A
        if((context->running_data.b->relay_status_secc.contact_c1 == OPENCHAOJI_GBT27930_B_CONTACT_STATUS_CLOSED)
            && (context->running_data.b->relay_status_secc.contact_c2 == OPENCHAOJI_GBT27930_B_CONTACT_STATUS_CLOSED)
            && (context->running_data.b->charging.charging_evcc_hal_samp.current < 50))
        {
            LOG_STATUS_CHANGE("[%d]sample_current<=5A C1C2 Opened");
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T1);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T2_EVCC);

            //可进行 C5C6黏连监测
            //断开C5C6
            OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);
            context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state = 0x01;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_fault_evcc_state 0x00->0x01", context->tag);
        }
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state == 0x01)
    {
        //等待C5C6断开，断开S2
        if(OpenChaoJi_evcc_hal_get_status_dc_relay(context->hal_handle)  == 0)
        {
            LOG_STATUS_CHANGE("[%d]C5C6 opened", context->tag);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T2);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T3_EVCC);

            OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle, 0);
            context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state = 0x02;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_fault_evcc_state 0x01->0x02", context->tag);
        }
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state == 0x02)
    {
        //等待分S2成功 且 监测点2电压  在2.34v 10.8v 8.73v 区段
        enum OpenChaoJi_pilot_status_gbt18487_b status_b = OpenChaoJi_evcc_utility_pilot_status_b(context->context_pilot);
        if ((!OpenChaoJi_evcc_hal_gbt_b_is_closed_s2(context->hal_handle))
            && ((status_b == OPENCHAOJI_PILOT_STATUS_GBT18487_B_B) || (status_b == OPENCHAOJI_PILOT_STATUS_GBT18487_B_C) || (status_b == OPENCHAOJI_PILOT_STATUS_GBT18487_B_Ap)))
        {
            LOG_STATUS_CHANGE("[%d]S2 opened", context->tag);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T3);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T4_EVCC);
            context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state = 0x03;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_fault_evcc_state 0x02->0x03", context->tag);
        }
        else
        {
            //超时前重复尝试关闭S2
            OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle, 0);
        }

    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state == 0x03)
    {
        //等待电压下降OpenChaoJi_evcc_hal_sampling_value < 60 V 外侧电压
        OpenChaoJi_evcc_hal_sampling_value(context->hal_handle, &context->running_data.b->charging.charging_evcc_hal_samp);
        LOG_DATA_NORMAL("[%d]voltage_out:%d", context->tag, context->running_data.b->charging.charging_evcc_hal_samp.voltage_out);
        if(context->running_data.b->charging.charging_evcc_hal_samp.voltage_out < 600)
        {
            LOG_STATUS_CHANGE("[%d]voltage_out<60V, Unlock", context->tag);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T4);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T5, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T5_EVCC);

            OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle, 0);
            context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state = 0x04;

            LOG_STATUS_CHANGE("[%d]statistics_stoping_fault_evcc_state 0x03->0x04", context->tag);
        }
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state == 0x04)
    {
        //等待分电子锁成功
        if(OpenChaoJi_evcc_hal_gbt_b_is_locked(context->hal_handle)==0)
        {
            LOG_STATUS_CHANGE("[%d]Unlocked", context->tag);
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T5);

            OpenChaoJi_evcc_hal_gbt_b_close_s2p(context->hal_handle, 0);

            context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state = 0x05;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_fault_evcc_state 0x04->0x05", context->tag);
        }
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Fault_Tv))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_Tv);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T1);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T2);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T3);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T4);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T5);

        OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_close_s2p(context->hal_handle, 0);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_fault_evcc_state [%02x]->0x05 because Tv timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state = 0x05;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Fault_T1))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T1);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T2_EVCC);

        // 可进行 C5C6黏连监测
        // 断开C5C6
        OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_fault_evcc_state [0x%02x]->0x01 because T1 timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state = 0x01;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Fault_T2))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T2);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T3_EVCC);

        //断开S2
        OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle,0);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_fault_evcc_state [[0x%02x]->0x02 because T2 C5/C6 disconnect timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state = 0x02;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Fault_T3))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T3);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T4_EVCC);

        OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle, 0);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_fault_evcc_state [0x%02x]->0x03 because T3 s2 disconnect timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state = 0x03;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Fault_T4))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T4);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Fault_T5, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_FAULT_T5_EVCC);
        OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle,0);
        OpenChaoJi_evcc_hal_gbt_b_close_s2p(context->hal_handle, 0);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_fault_evcc_state [0x%02x]->0x04 because T4 The vehicle interface voltage vent timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state = 0x04;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Fault_T5))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T5);
        LOG_NOTICE("[%d] statistics_stoping_fault_evcc_state [0x%02x]->0x05 because T5 The electronic lock unlock timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state = 0x05;
    }

    if(context->running_data.b->statistics_stoping.statistics_stoping_fault_evcc_state == 0x05)
    {
        OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_close_s2p(context->hal_handle, 0);

        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_Tv);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T1);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T2);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T3);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Fault_T4);

        // 服务统计协商成功
        if (context->running_data.b->func_nego.func_support_evcc.fdc_statistics == OPENCHAOJI_GBT27930_B_FDC_SUPPORT_TYPE_SUPPORT)
        {
            // 发送“车辆阶段确认信息”报文
            //OpenChaoJi_gbt27930_b_evcc_next_phase_info_send(context);
            // 打开T0
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.State_Tv, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_STATE_TV_EVCC);

            LOG_STATUS_CHANGE("[%d]Stoping Charge S1 To S3", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S3_PHASE_CONFIRM;
        }
        else
        {
            // 退出流程
            LOG_STATUS_CHANGE("[%d]Stoping Charge S1 Exit", context->tag);

            // 根据功能协商结果进入下一功能模块FDC
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S0_FINISHING;
        }
    }
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S1_FAULT;
}


#define OpenChaoJi_gbt27930_b_evcc_post_statistics_stoping_s2_emrge         NULL

void OpenChaoJi_gbt27930_b_evcc_prev_statistics_stoping_s2_emrge(struct OpenChaoJi_evcc_context * context)
{
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_Tv, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_TV_EVCC);
    context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state = 0x00;
}

static int  OpenChaoJi_gbt27930_b_evcc_loop_statistics_stoping_s2_emrge(struct OpenChaoJi_evcc_context * context)
{
    //紧急停机;
    if(context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state == 0x00)
    {
        //断开S2
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T1, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T1_EVCC);
        OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle,0);

        context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state = 0x01;
        LOG_STATUS_CHANGE("[%d]statistics_stoping_emergency_evcc_state 0x00->0x01", context->tag);
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state == 0x01)
    {
        OpenChaoJi_evcc_hal_sampling_value(context->hal_handle, &context->running_data.b->charging.charging_evcc_hal_samp);
        LOG_DATA_NORMAL("[%d]sample_current:%d c1:%d c2:%d", context->tag
            , context->running_data.b->charging.charging_evcc_hal_samp.current
            , context->running_data.b->relay_status_secc.contact_c1
            , context->running_data.b->relay_status_secc.contact_c2);
        //S2已断开
        if(!OpenChaoJi_evcc_hal_gbt_b_is_closed_s2(context->hal_handle))
        {
            //等待电流降至5A以下,断开C5C6
            if(context->running_data.b->charging.charging_evcc_hal_samp.current < 50)
            {
                LOG_STATUS_CHANGE("[%d]sample_current<=5A Emergency", context->tag);
                OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T1);
                OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T2_EVCC);

                //断开C5C6
                OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);
                context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state = 0x02;
                LOG_STATUS_CHANGE("[%d]statistics_stoping_emergency_evcc_state 0x01->0x02", context->tag);
            }
        }
        else
        {
            OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle, 0);
        }
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state == 0x02)
    {
        //等待C5C6断开
        if(OpenChaoJi_evcc_hal_get_status_dc_relay(context->hal_handle) == 0)
        {
            LOG_STATUS_CHANGE("[%d]C5C6 opened", context->tag);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T2);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T3_EVCC);
            context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state = 0x03;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_emergency_evcc_state 0x02->0x03", context->tag);
        }
        else
        {
            OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);
        }
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state == 0x03)
    {
        //等待电压下降OpenChaoJi_evcc_hal_sampling_value < 60 V 外侧电压
        OpenChaoJi_evcc_hal_sampling_value(context->hal_handle, &context->running_data.b->charging.charging_evcc_hal_samp);
        LOG_DATA_NORMAL("[%d]voltage_out:%d", context->tag, context->running_data.b->charging.charging_evcc_hal_samp.voltage_out);
        if(context->running_data.b->charging.charging_evcc_hal_samp.voltage_out < 600)
        {
            LOG_STATUS_CHANGE("[%d]voltage_out<60V, Unlock", context->tag);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T3);
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T4_EVCC);

            OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle,0);
            context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state = 0x04;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_emergency_evcc_state 0x03->0x04", context->tag);
        }
    }
    else if(context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state == 0x04)
    {
        //等待分电子锁成功
        if(OpenChaoJi_evcc_hal_gbt_b_is_locked(context->hal_handle) == 0)
        {
            LOG_STATUS_CHANGE("[%d]Unlocked", context->tag);
            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T4);

            OpenChaoJi_evcc_hal_gbt_b_close_s2p(context->hal_handle, 0);

            context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state = 0x05;
            LOG_STATUS_CHANGE("[%d]statistics_stoping_emergency_evcc_state 0x04->0x05", context->tag);
        }
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Emrge_Tv))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_Tv);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T1);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T2);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T3);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T4);

        OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle,0);
        OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_close_s2p(context->hal_handle, 0);

        LOG_STATUS_CHANGE("[%d] statistics_stoping_emergency_evcc_state [0x%02x]->0x05 because Tv timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state = 0x05;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Emrge_T1))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T1);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T2, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T2_EVCC);
        //断开c5c6
        OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);
        LOG_STATUS_CHANGE("[%d] statistics_stoping_emergency_evcc_state [0x%02x]->0x02 because T1 The current drops to 5A timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state = 0x02;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Emrge_T2))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T2);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T3, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T3_EVCC);
        //超时内循环断开C5C6
        OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);
        LOG_STATUS_CHANGE("[%d] statistics_stoping_emergency_evcc_state [0x%02x]->0x03 because T2 C5/C6 disconnect timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state = 0x03;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Emrge_T3))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T3);
        OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.Emrge_T4, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_EMRGE_T4_EVCC);

        OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle,0);
        LOG_STATUS_CHANGE("[%d] statistics_stoping_emergency_evcc_state [0x%02x]->0x04 because T3 The vehicle interface voltage vent timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state = 0x04;
    }

    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.Emrge_T4))
    {
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T4);
        OpenChaoJi_evcc_hal_gbt_b_close_s2p(context->hal_handle, 0);
        LOG_STATUS_CHANGE("[%d] statistics_stoping_emergency_evcc_state [0x%02x]->0x05 because T4 The electronic lock unlock timeout", context->tag, context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state);
        context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state = 0x05;
    }

    if(context->running_data.b->statistics_stoping.statistics_stoping_emergency_evcc_state == 0x05)
    {
        OpenChaoJi_evcc_hal_gbt_b_close_s2(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_close_dc_relay(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_lock(context->hal_handle, 0);
        OpenChaoJi_evcc_hal_gbt_b_close_s2p(context->hal_handle, 0);

        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_Tv);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T1);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T2);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T3);
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.Emrge_T4);

        // 服务统计协商成功
        if (context->running_data.b->func_nego.func_support_evcc.fdc_statistics == OPENCHAOJI_GBT27930_B_FDC_SUPPORT_TYPE_SUPPORT)
        {
            // 发送“车辆阶段确认信息”报文
            //OpenChaoJi_gbt27930_b_evcc_next_phase_info_send(context);
            // 打开T0
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics_stoping.State_Tv, OPENCHAOJI_GBT27930_B_PID_TIMEOUT_STATISTICS_STOPPING_STATE_TV_EVCC);

            LOG_STATUS_CHANGE("[%d]Stoping Charge S2 To S3", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S3_PHASE_CONFIRM;
        }
        else
        {
            // 退出流程
            LOG_STATUS_CHANGE("[%d]Stoping Charge S2 Exit", context->tag);
            // 根据功能协商结果进入下一功能模块FDC
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S0_FINISHING;
        }
    }
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S2_EMRGE;
}
#define OpenChaoJi_gbt27930_b_evcc_prev_statistics_stoping_s3_phase_confirm         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_statistics_stoping_s3_phase_confirm         NULL

static int  OpenChaoJi_gbt27930_b_evcc_loop_statistics_stoping_s3_phase_confirm(struct OpenChaoJi_evcc_context * context)
{
    // 接收"充电机阶段信息"报文
    if (context->running_data.b->phase_info_secc_ok)
    {
        LOG_STATUS_CHANGE("[%d]Stoping Charge S3 Receive Phase Info From SECC", context->tag);

        // 车辆判断是否支持
        if (context->running_data.b->func_nego.func_support_evcc.fdc_statistics == context->running_data.b->phase_info_secc.fdc_type && \
			context->running_data.b->phase_info_secc.fc_type == OPENCHAOJI_GBT27930_B_FC_TYPE_STATISTICS)
        {
            //发送"车辆阶段确认_成功"报文
            LOG_STATUS_CHANGE("[%d]Stoping Charge S3 Send Vehicle Phase Confirm Success", context->tag);
            OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_SUCCEED);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.State_Tv);

            // 进入下一阶段
            LOG_STATUS_CHANGE("[%d]Stoping Charge S3 To Statistics Charge S0", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STATISTICS_S0_INIT;
        }else{
            //发送"车辆阶段确认_失败"报文
            LOG_STATUS_CHANGE("[%d]Stoping Charge S3 Send Vehicle Phase Confirm Failed", context->tag);
            OpenChaoJi_gbt27930_b_evcc_phase_ack_send(context, OPENCHAOJI_GBT27930_B_PHASE_ACK_FAILED);

            OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.State_Tv);

            // 阶段确认失败 退出
            LOG_NOTICE("[%d]Stoping Charge S3 Exit", context->tag);
            return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S0_FINISHING;
        }
    }

    // 阶段定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics_stoping.State_Tv))
    {
        LOG_STATUS_CHANGE("[%d]Stoping Charge S3 Send Stop Vehicle Stop Timeout", context->tag);

        //  发送"中止_阶段确认超时"报文 服务统计
        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_STATISTICS);

        // 关闭TV
        OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics_stoping.State_Tv);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S0_FINISHING;
    }

    return  OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S3_PHASE_CONFIRM;
}

const struct OpenChaoJi_evcc_module_status c_sytem_b_evcc_status_array_statistics_stoping[OPENCHAOJI_GBT27930_B_EVCC_STATUS_STOPING_END_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S0_NORMAL,
        .name = "Stoping.S0.Init",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_statistics_stoping_s0_normal,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_statistics_stoping_s0_normal,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_statistics_stoping_s0_normal,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S1_FAULT,
        .name = "Stoping.S1.Wait",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_statistics_stoping_s1_fault,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_statistics_stoping_s1_fault,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_statistics_stoping_s1_fault,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S2_EMRGE,
        .name = "Stoping.S2.Emrge",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_statistics_stoping_s2_emrge,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_statistics_stoping_s2_emrge,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_statistics_stoping_s2_emrge,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S3_PHASE_CONFIRM,
        .name = "Stoping.S3.PhaseConfirm",

        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_statistics_stoping_s3_phase_confirm,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_statistics_stoping_s3_phase_confirm,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_statistics_stoping_s3_phase_confirm,
    },

};

const struct OpenChaoJi_evcc_module c_gbt27930_b_evcc_module_statistics_stoping =
{
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_STATISTICS_STOPING,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_SERVICE_STOPPING,
    .fdc_type = 1,
    .name = "STOPPING",
    .status_array = c_sytem_b_evcc_status_array_statistics_stoping,
    .status_array_len = OPENCHAOJI_GBT27930_B_EVCC_STATUS_STOPING_END_NUM,
};



/* -------------- 服务统计 模块 长园 -------------- */
#define OpenChaoJi_gbt27930_b_evcc_prev_statistics_s0_init         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_statistics_s0_init         NULL
static int  OpenChaoJi_gbt27930_b_evcc_loop_statistics_s0_init(struct OpenChaoJi_evcc_context * context)
{
    // 初始化
    LOG_STATUS_CHANGE("[%d]STATISTICS S0 init start", context->tag);
    context->running_data.b->statistics.statistics_secc_ok = 0;

    // 打开Tv
    OpenChaoJi_os_soft_timer_start(&context->running_data.b->statistics.Tv, OPENCHAOJI_GBT27930_B_PID_TV_TIMEOUT_STATISTICS_EVCC);
    LOG_STATUS_CHANGE("[%d]STATISTICS S0 Tv start", context->tag);

    // 进入S1
    LOG_STATUS_CHANGE("[%d]STATISTICS S0 goto S1", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STATISTICS_S1_WAIT_EV_PACKET;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_statistics_s1_wait_se_packet         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_statistics_s1_wait_se_packet         NULL
static int  OpenChaoJi_gbt27930_b_evcc_loop_statistics_s1_wait_se_packet(struct OpenChaoJi_evcc_context * context)
{
    // 接收"充电机统计信息"报文
    if (context->running_data.b->statistics.statistics_secc_ok)
    {
        // 发送"车辆统计信息"报文
        LOG_STATUS_CHANGE("[%d]STATISTICS S1 Recv secc statistics packet and send evcc statistics packet", context->tag);
        context->running_data.b->statistics.statistics_evcc.charge_stop_SOC = OpenChaoJi_evcc_hal_get_batt_soc(context->hal_handle);
		OpenChaoJi_gbt27930_b_evcc_send_normal(context, OPENCHAOJI_GBT27930_B_PID_TAG_STATISTICS_EVCC, (uint8_t *)(&context->running_data.b->statistics.statistics_evcc), sizeof(context->running_data.b->statistics.statistics_evcc));

        // 进入S2
        LOG_STATUS_CHANGE("[%d]STATISTICS S1 goto S2", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STATISTICS_S2_RETURN;
    }

    // Tv定时器到
    if (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->statistics.Tv))
    {
        // 发送"中止_服务统计超时"报文
        LOG_STATUS_CHANGE("[%d]STATISTICS S1 Tv timeout and send stop info packet", context->tag);

        OpenChaoJi_gbt27930_b_evcc_stop_info_send(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_COMM_TIMEOUT, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TIMEOUT_STATISTICS);

        // 进入S2
        LOG_STATUS_CHANGE("[%d]STATISTICS S1 goto S2", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STATISTICS_S2_RETURN;
    }

    // 未收到, 未超时, 继续等待
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STATISTICS_S1_WAIT_EV_PACKET;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_statistics_s2_return         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_statistics_s2_return         NULL
static int  OpenChaoJi_gbt27930_b_evcc_loop_statistics_s2_return(struct OpenChaoJi_evcc_context * context)
{
    // 关闭Tv定时器
    LOG_STATUS_CHANGE("[%d]STATISTICS S2 Close Tv");
    OpenChaoJi_os_soft_timer_stop(&context->running_data.b->statistics.Tv);

    // 退出充电过程
    LOG_STATUS_CHANGE("[%d]STATISTICS S2 Exit charging process", context->tag);
    return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S0_FINISHING;
}

const struct OpenChaoJi_evcc_module_status c_sytem_b_evcc_status_array_statistics[OPENCHAOJI_GBT27930_B_EVCC_STATUS_STATISTICS_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STATISTICS_S0_INIT,
        .name = "STATISTICS.S0.Init",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_statistics_s0_init,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_statistics_s0_init,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_statistics_s0_init,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STATISTICS_S1_WAIT_EV_PACKET,
        .name = "STATISTICS.S1.WaitSeccPacket",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_statistics_s1_wait_se_packet,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_statistics_s1_wait_se_packet,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_statistics_s1_wait_se_packet,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STATISTICS_S2_RETURN,
        .name = "STATISTICS.S2.Return",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_statistics_s2_return,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_statistics_s2_return,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_statistics_s2_return,
    },
};

const struct OpenChaoJi_evcc_module c_gbt27930_b_evcc_module_statistics =
{
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_STATISTICS,
    .fc_type = OPENCHAOJI_GBT27930_B_FC_TYPE_STATISTICS,
    .fdc_type = OPENCHAOJI_GBT27930_B_FDC_STATISTICS,
    .status_array = c_sytem_b_evcc_status_array_statistics,
    .status_array_len = OPENCHAOJI_GBT27930_B_EVCC_STATUS_STATISTICS_NUM,
};




/* -------------- END 模块 星星 -------------- */
#define OpenChaoJi_gbt27930_b_evcc_prev_end_s0_finishing         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_end_s0_finishing         NULL

static int OpenChaoJi_gbt27930_b_evcc_loop_end_s0_finishing(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_CHANGE("[%d]END s0", context->tag);

    context->app_permit_charge = 0;

    OpenChaoJi_gbt27930_b_evcc_running_data_timer_reset(context);

	OpenChaoJi_evcc_utility_session_stop(context->context_session);
    OpenChaoJi_evcc_utility_pilot_reset(context->context_pilot);

	return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S1_FINISHED;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_end_s1_finished         NULL
#define OpenChaoJi_gbt27930_b_evcc_post_end_s1_finished         NULL

static int OpenChaoJi_gbt27930_b_evcc_loop_end_s1_finished(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_LOOP("[%d]END s1", context->tag);

    // 拔枪进入IDLE
    if (!OpenChaoJi_evcc_utility_pilot_is_secc_connected(context->context_pilot))
    {
        LOG_STATUS_CHANGE("[%d]END S1: SECC Disconnected", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_IDLE_S0_IDLE;
    }

    // 不拔枪启动第二次充电
    if (context->app_permit_charge)
    {
        LOG_STATUS_CHANGE("[%d]END S1: App Start Charge", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_IDLE_S0_IDLE;
    }

	return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S1_FINISHED;
}

const struct OpenChaoJi_evcc_module_status c_sytem_b_evcc_status_array_end[OPENCHAOJI_GBT27930_B_EVCC_STATUS_END_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S0_FINISHING,
		.name = "End.S0.Finishing",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_end_s0_finishing,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_end_s0_finishing,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_end_s0_finishing,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S1_FINISHED,
		.name = "End.S1.Finished",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_end_s1_finished,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_end_s1_finished,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_end_s1_finished,
    },
};

const struct OpenChaoJi_evcc_module c_gbt27930_b_evcc_module_end =
{
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_END,
    .fc_type = 2,
    .fdc_type = 1,
    .name = "END",
    .status_array = c_sytem_b_evcc_status_array_end,
    .status_array_len = OPENCHAOJI_GBT27930_B_EVCC_STATUS_END_NUM,
};




/* -------------- FAULT 模块 星星 -------------- */

#define OpenChaoJi_gbt27930_b_evcc_prev_fault_s0_wait			NULL
#define OpenChaoJi_gbt27930_b_evcc_post_fault_s0_wait			NULL

static int OpenChaoJi_gbt27930_b_evcc_loop_fault_s0_wait(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_CHANGE("[%d] Fault start s0", context->tag);

    context->app_permit_charge = 0;

    OpenChaoJi_gbt27930_b_evcc_running_data_timer_reset(context);

	OpenChaoJi_evcc_utility_session_stop(context->context_session);
    OpenChaoJi_evcc_utility_pilot_reset(context->context_pilot);

	return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S1_FINISHED;
}

#define OpenChaoJi_gbt27930_b_evcc_prev_fault_s1_return			NULL
#define OpenChaoJi_gbt27930_b_evcc_post_fault_s1_return			NULL

static int OpenChaoJi_gbt27930_b_evcc_loop_fault_s1_return(struct OpenChaoJi_evcc_context * context)
{
    LOG_STATUS_LOOP("[%d] Fault start s1", context->tag);

    // 拔枪进入IDLE
    if (!OpenChaoJi_evcc_utility_pilot_is_secc_connected(context->context_pilot))
    {
        LOG_STATUS_CHANGE("[%d] Fault S1: SECC Disconnected", context->tag);
        return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_IDLE_S0_IDLE;
    }

	return OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S1_FINISHED;
}

const struct OpenChaoJi_evcc_module_status c_sytem_b_evcc_status_array_fault[OPENCHAOJI_GBT27930_B_EVCC_STATUS_FAULT_NUM] = {
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FAULT_S0_WAIT,
		.name = "fault.s0",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_fault_s0_wait,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_fault_s0_wait,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_fault_s0_wait,
    },
    {
        .module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FAULT_S1_RETURN,
		.name = "fault.s1",
        .prev_func = OpenChaoJi_gbt27930_b_evcc_prev_fault_s1_return,
        .post_func = OpenChaoJi_gbt27930_b_evcc_post_fault_s1_return,
        .loop_func = OpenChaoJi_gbt27930_b_evcc_loop_fault_s1_return,
    },
};

const struct OpenChaoJi_evcc_module c_gbt27930_b_evcc_module_fault =
{
    .module_id = OPENCHAOJI_GBT27930_B_MODULE_FAULT,
    .fc_type = 3,
    .fdc_type = 1,
    .name = "FAULT",
    .status_array = c_sytem_b_evcc_status_array_fault,
    .status_array_len = OPENCHAOJI_GBT27930_B_EVCC_STATUS_FAULT_NUM,
};





/**
 * 通用子模块处理, 即跨越一般功能模块的一些全局功能的处理. 例如链路检测, 连接检测等
 * 由于连接检测需要快速响应, 厂家底层实现时可以考虑通过中断等方式触发后立即调用service方法来触发处理流程, 而不必等到定时处理
*/


static int OpenChaoJi_gbt27930_b_evcc_sub_module_func(struct OpenChaoJi_evcc_context * context)
{
    // TODO: 各种错误处理, 参考18487和27930
	if ((context->current_module_status_id >= OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S1_NEGO)
	&& (context->current_module_status_id < OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S0_NORMAL))
	{
		if (!OpenChaoJi_evcc_utility_session_is_connected(context->context_session))
		{
			LOG_ERR("[%d]LostConnection", context->context_session);
            return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TERM_FAILURE);
		}
	}

    if ((context->current_module_status_id >= OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S3_CONFIRM_SECC_READY) && (context->current_module_status_id < OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S0_NORMAL))
    {
        if (OpenChaoJi_evcc_hal_is_emergency_pushed(context->hal_handle))
        {
            LOG_EMERG("[%d]EmergencyPushed", context->context_session);
            return OpenChaoJi_gbt27930_b_evcc_stop_emergency(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TERM_FAILURE);
        }
    }

    //导引异常判断
    if (context->current_module_status_id > OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S3_CONFIRM_SECC_READY\
            && context->current_module_status_id < OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S0_INIT)
    {
        #if(OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_RESERVE == CONFIG_YES)
        {
            if (OPENCHAOJI_MODULE_OF_ID(context->current_module_status_id) == OPENCHAOJI_GBT27930_B_MODULE_RESERVE)
            {
                enum OpenChaoJi_pilot_status_gbt18487_b status = OpenChaoJi_evcc_utility_pilot_status_b(context->context_pilot);
                //预约阶段，存在S1动作，判断是否插枪和secc允许充电
                if ((OPENCHAOJI_PILOT_STATUS_GBT18487_B_C != status) && (OPENCHAOJI_PILOT_STATUS_GBT18487_B_B != status))
                {
                    LOG_CRIT("pilot abnormal");
                    return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TERM_FAILURE);
                }
            }
            else if (!OpenChaoJi_evcc_utility_pilot_b_is_secc_permit_charge(context->context_pilot))
            {
                LOG_CRIT("pilot abnormal");
                return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TERM_FAILURE);
            }
        }
        #else
        {
            if (!OpenChaoJi_evcc_utility_pilot_b_is_secc_permit_charge(context->context_pilot))
            {
                LOG_CRIT("pilot abnormal");
                return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TERM_FAILURE);
            }
        }
        #endif
    }

    if (context->current_module_status_id >= OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_SELF_CHECK_S2_CHECKING\
            && context->current_module_status_id < OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_STOPING_S0_NORMAL)
    {
        if (!OpenChaoJi_evcc_utility_pilot_b_is_all_permit_charge(context->context_pilot))
        {
            LOG_CRIT("[%d]pilot Emergency", context->tag);
            return OpenChaoJi_gbt27930_b_evcc_stop_failed(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TERM_EMERGENCY);
        }
    }

	if (context->current_module_status_id >= OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_TRIGGER_S0_CONFIRM_CONNECT
		&& context->current_module_status_id < OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_CHARGING_S0_INIT)	// 待讨论？能量传输各状态已有停机判断，sub_module改为在能量传输前判断
	{
	    if (!context->app_permit_charge)
	    {
	        LOG_WARNING("[%d]AppStop", context->context_session);
	        return OpenChaoJi_gbt27930_b_evcc_stop_normal(context, OPENCHAOJI_GBT27930_B_END_CODE_EVCC_TERM, OPENCHAOJI_GBT27930_B_END_REASON_EVCC_TERM_NORMAL);
	    }

		if(context->running_data.b->stop_info_secc_ok)
		{
			LOG_WARNING("[%d]EVCCStop", context->tag);
            return OpenChaoJi_gbt27930_b_evcc_stop_normal(context, 0, 0);
		}
	}

    /*公共报文周期发送+突传*/
    if (context->current_module_status_id >= OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_FUNC_NEGO_S3_SUCCEED
		&& context->current_module_status_id < OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_END_S0_FINISHING)
    {
        /*启动公共报文定时器*/

        //接触器状态报文
        if (OpenChaoJi_os_soft_timer_is_stopped(&context->running_data.b->relay_status_evcc_T1))
        {
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->relay_status_evcc_T1, OPENCHAOJI_GBT27930_B_PID_TIMELOOP_RELAY_STATUS_EVCC);
        }

        unsigned char hal_relay_status_evcc = OpenChaoJi_evcc_hal_get_status_dc_relay(context->hal_handle);
        if ((hal_relay_status_evcc != context->running_data.b->hal_relay_status_evcc)
        || (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->relay_status_evcc_T1)))
        {
            context->running_data.b->hal_relay_status_evcc = hal_relay_status_evcc;
            OpenChaoJi_gbt27930_b_evcc_relay_info_send(context, hal_relay_status_evcc);
        }

        //电子锁状态报文
        if (OpenChaoJi_os_soft_timer_is_stopped(&context->running_data.b->latching_status_T1))
        {
            OpenChaoJi_os_soft_timer_start(&context->running_data.b->latching_status_T1, OPENCHAOJI_GBT27930_B_PID_TIMELOOP_LATCHING_STATUS_EVCC);
            LOG_STATUS_CHANGE("[%d]C5C6 Elock T1 start", context->tag);
        }

        unsigned char latching_status_evcc = OpenChaoJi_evcc_hal_gbt_b_is_locked(context->hal_handle);
        if ((latching_status_evcc != context->running_data.b->hal_latching_status_evcc)
        || (OpenChaoJi_os_soft_timer_is_timeout(&context->running_data.b->latching_status_T1)))
        {
            context->running_data.b->hal_latching_status_evcc = latching_status_evcc;
            OpenChaoJi_gbt27930_b_evcc_elock_info_send(context, latching_status_evcc);
        }
    }

    return context->current_module_status_id;
}

/**
 * 收发数据的通用处理方法
 * 收是在执行所有system操作前统一执行, 用于同步对端状态
 * 发是在执行所有system后统一执行, 用于把本方状态同步给对端
*/
void OpenChaoJi_gbt27930_b_evcc_data_read_func(struct OpenChaoJi_evcc_context * context)
{
    // 先把对端数据都收过来
    OpenChaoJi_evcc_utility_session_service_try_recv(context->context_session);

    // 读空缓冲区, 解析到system数据处理区
    struct OpenChaoJi_utility_data_buff_recv_data recv_data;
    while (OpenChaoJi_evcc_utility_session_data_read(context->context_session, &recv_data) == 0)
    {
        OpenChaoJi_gbt27930_b_evcc_parse_data(context, &recv_data);
        if (!recv_data.recv_data.src_free)
        {
            OpenChaoJi_os_free(recv_data.recv_data.data);
        }
    }
}

void OpenChaoJi_gbt27930_b_evcc_data_write_func(struct OpenChaoJi_evcc_context * context)
{
    OpenChaoJi_evcc_utility_session_service_try_send(context->context_session);
}

/**
 * 启停充电/获取充电等方法, 供App调用
*/
int OpenChaoJi_gbt27930_b_evcc_app_start_func(struct OpenChaoJi_evcc_context * context, struct OpenChaoJi_evcc_app_start_parameter * app_start_parameter)
{
    LOG_ALERT("[%d]evcc_app_start_func", context->tag);

    context->running_data.b->app_start_parameter = *app_start_parameter;
    context->app_permit_charge = 1;

    return 0;
}
int OpenChaoJi_gbt27930_b_evcc_app_stop_func(struct OpenChaoJi_evcc_context * context)
{
    LOG_ALERT("[%d]evcc_app_stop_func", context->tag);

    context->app_permit_charge = 0;

    return 0;
}

int  OpenChaoJi_gbt27930_b_evcc_app_get_status_func(struct OpenChaoJi_evcc_context * context, struct OpenChaoJi_evcc_context_status * status)
{
    status->current_module_status_id = context->current_module_status_id;
    return 0;
}

int OpenChaoJi_evcc_create_system_gbt27930_b(struct OpenChaoJi_evcc_context * context)
{
    /* 注册evcc系统, 生成evcc系统模块状态表 */
    context->evcc_gbt27930_system_b = OpenChaoJi_os_malloc(sizeof(struct OpenChaoJi_evcc_gbt27930_system));
    if (context->evcc_gbt27930_system_b == NULL)
    {
        goto FAILED_CREATE;
    }
	memset(context->evcc_gbt27930_system_b, 0x00, sizeof(struct OpenChaoJi_evcc_gbt27930_system));

    context->evcc_gbt27930_system_b->name = "EVCC_GBT27930_B";

    context->evcc_gbt27930_system_b->module_array = OpenChaoJi_os_malloc(OPENCHAOJI_GBT27930_B_MODULE_NUM * sizeof(struct OpenChaoJi_evcc_module *));

    if (context->evcc_gbt27930_system_b->module_array == NULL)
    {
        goto FAILED_CREATE;
    }

	memset(context->evcc_gbt27930_system_b->module_array, 0x00, OPENCHAOJI_GBT27930_B_MODULE_NUM * sizeof(struct OpenChaoJi_evcc_module *));
	context->evcc_gbt27930_system_b->module_array_len = OPENCHAOJI_GBT27930_B_MODULE_NUM;

    /* -------------- IDLE 模块 特来电 -------------- */
    context->evcc_gbt27930_system_b->module_array[OPENCHAOJI_GBT27930_B_MODULE_IDLE]            = &c_gbt27930_b_evcc_module_idle;
    /* -------------- Trigger 模块 特来电 -------------- */
    context->evcc_gbt27930_system_b->module_array[OPENCHAOJI_GBT27930_B_MODULE_TRIGGER]         = &c_gbt27930_b_evcc_module_trigger;
    /* -------------- 功能协商 模块 嘉盛 -------------- */
    context->evcc_gbt27930_system_b->module_array[OPENCHAOJI_GBT27930_B_MODULE_FUNC_NEGO]       = &c_gbt27930_b_evcc_module_func_nego;
    /* -------------- 参数配置 模块 嘉盛 -------------- */
    context->evcc_gbt27930_system_b->module_array[OPENCHAOJI_GBT27930_B_MODULE_PARAM_CONFIG]    = &c_gbt27930_b_evcc_module_param_config;
    /* -------------- 授权(RFID) 模块 鲁软 -------------- */
    context->evcc_gbt27930_system_b->module_array[OPENCHAOJI_GBT27930_B_MODULE_AUTH_RFID]       = &c_gbt27930_b_evcc_module_auth_rfid;
    /* -------------- 授权(EVIN) 模块 鲁软 -------------- */
    context->evcc_gbt27930_system_b->module_array[OPENCHAOJI_GBT27930_B_MODULE_AUTH_EVIN]       = &c_gbt27930_b_evcc_module_auth_evin;
    /* -------------- 预约 模块 (暂空) -------------- */
    context->evcc_gbt27930_system_b->module_array[OPENCHAOJI_GBT27930_B_MODULE_RESERVE]         = NULL;
    /* -------------- 系统自检 模块 领充 -------------- */
    context->evcc_gbt27930_system_b->module_array[OPENCHAOJI_GBT27930_B_MODULE_SELFCHECK]       = &c_gbt27930_b_evcc_module_self_check;
    /* -------------- 预充及能量传输 模块 鲁软 -------------- */
	context->evcc_gbt27930_system_b->module_array[OPENCHAOJI_GBT27930_B_MODULE_CHARGING]   = &c_gbt27930_b_evcc_module_charging;
   /* -------------- 服务统计停止中 模块 鲁软 -------------- */
    context->evcc_gbt27930_system_b->module_array[OPENCHAOJI_GBT27930_B_MODULE_STATISTICS_STOPING] = &c_gbt27930_b_evcc_module_statistics_stoping;
    /* -------------- 服务统计 模块 长园 -------------- */
    context->evcc_gbt27930_system_b->module_array[OPENCHAOJI_GBT27930_B_MODULE_STATISTICS]      = &c_gbt27930_b_evcc_module_statistics;
    /* -------------- END 模块 星星 -------------- */
	context->evcc_gbt27930_system_b->module_array[OPENCHAOJI_GBT27930_B_MODULE_END]				= &c_gbt27930_b_evcc_module_end;
    /* -------------- FAULT 模块 星星 -------------- */
	context->evcc_gbt27930_system_b->module_array[OPENCHAOJI_GBT27930_B_MODULE_FAULT]			= &c_gbt27930_b_evcc_module_fault;

    /* -------------- 通用功能 鲁软 -------------- */
    context->evcc_gbt27930_system_b->sub_module_func        = OpenChaoJi_gbt27930_b_evcc_sub_module_func;
    context->evcc_gbt27930_system_b->data_read_func         = OpenChaoJi_gbt27930_b_evcc_data_read_func;
    context->evcc_gbt27930_system_b->data_write_func        = OpenChaoJi_gbt27930_b_evcc_data_write_func;
    context->evcc_gbt27930_system_b->app_start_func         = OpenChaoJi_gbt27930_b_evcc_app_start_func;
    context->evcc_gbt27930_system_b->app_stop_func          = OpenChaoJi_gbt27930_b_evcc_app_stop_func;
    context->evcc_gbt27930_system_b->app_get_status_func    = OpenChaoJi_gbt27930_b_evcc_app_get_status_func;

    /* 创建运行时数据 */
    context->running_data.b = OpenChaoJi_os_malloc(sizeof(struct OpenChaoJi_evcc_gbt27930_b_data));
    if (context->running_data.b == NULL)
    {
        goto FAILED_CREATE;
    }
	// memset(context->running_data.b, 0x00, sizeof(struct OpenChaoJi_evcc_gbt27930_b_data));

    OpenChaoJi_gbt27930_b_evcc_running_data_reset(context);

    context->current_module_status_id = OPENCHAOJI_GBT27930_B_EVCC_STATUS_ID_IDLE_S0_IDLE;
    context->current_status_ticks = OpenChaoJi_os_get_ticks();

    return 0;

FAILED_CREATE:
    OpenChaoJi_evcc_destory_system_gbt27930_b(context);

    return -1;
}

/**
 * @brief: 销毁系统上下文
 * @param {OpenChaoJi_evcc_context *} context 系统上下文指针
 * @return {*}
 */
void OpenChaoJi_evcc_destory_system_gbt27930_b(struct OpenChaoJi_evcc_context * context)
{
    if (context->evcc_gbt27930_system_b != NULL)
    {
        if (context->evcc_gbt27930_system_b->module_array == NULL)
        {
            OpenChaoJi_os_free(context->evcc_gbt27930_system_b->module_array);
        }

        OpenChaoJi_os_free(context->evcc_gbt27930_system_b);
    }

    if (context->running_data.b != NULL)
    {
        OpenChaoJi_os_free(context->running_data.b);
    }
}

/**********************************以下为B类系统报文解析函数*******************************************/

/**
 * @brief  解析接收报文
 *
 * @param  context 系统上下文指针，包含必要的环境信息。
 * @param  recv_data 接收的数据结构
 * @return 成功返回0，失败返回-1。
 */
int OpenChaoJi_gbt27930_b_evcc_parse_data(struct OpenChaoJi_evcc_context * context, struct OpenChaoJi_utility_data_buff_recv_data * recv_data)
{
	if(recv_data->tag.gbt.msg_type != OPENCHAOJI_GBT27930_SYSTEM_B_MSG)
	{
        LOG_ERR("Not MsgType GBT-B");
        goto PARSE_FAILED;
    }

    struct OpenChaoJi_gbt27930_b_msg msg;
    if (!OpenChaoJi_gbt27930_b_msg_decode(&msg, recv_data->recv_data.data, recv_data->recv_data.len))
    {
        goto PARSE_FAILED;
    }

    bool changed = false;
    switch(recv_data->recv_data.data[0])
    {
    case OPENCHAOJI_GBT27930_B_PGI_FUNC_NEGO_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_func_support_secc(context->tag
            , &context->running_data.b->func_nego.func_support_secc
            , &msg.msg.func_support_secc
        );
        if (!context->running_data.b->func_nego.func_support_secc_ok)
        {
            LOG_WARNING("[%d]func_support_secc_ok", context->tag);
            context->running_data.b->func_nego.func_support_secc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_PARAM_CONFIG_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_param_config_secc(context->tag
            , &context->running_data.b->param_config.param_config_secc
            , &msg.msg.param_config_secc
        );
        if (!context->running_data.b->param_config.param_config_secc_ok)
        {
            LOG_WARNING("[%d]param_config_secc_ok", context->tag);
            context->running_data.b->param_config.param_config_secc_ok = 1;
            changed = true;
        }
        break;
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_AUTH == CONFIG_YES)
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_RFID == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_AUTH_RFID_PARAM_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_auth_rfid_param_secc(context->tag
            , &context->running_data.b->auth_rfid.rfid_param_secc
            , &msg.msg.auth_rfid_param_secc
        );
        if (!context->running_data.b->auth_rfid.rfid_param_secc_ok)
        {
            LOG_WARNING("[%d]rfid_param_secc_ok", context->tag);
            context->running_data.b->auth_rfid.rfid_param_secc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_AUTH_RFID_RESULT_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_auth_rfid_result_secc(context->tag
            , &context->running_data.b->auth_rfid.rfid_result_secc
            , &msg.msg.auth_rfid_result_secc
        );
        if (!context->running_data.b->auth_rfid.rfid_result_secc_ok)
        {
            LOG_WARNING("[%d]rfid_result_secc_ok", context->tag);
            context->running_data.b->auth_rfid.rfid_result_secc_ok = 1;
            changed = true;
        }
        break;
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_AUTH_EVIN == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_AUTH_EVIN_REQ_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_auth_evin_req_secc(context->tag
            , &context->running_data.b->auth_evin.evin_req_secc
            , &msg.msg.auth_evin_req_secc
        );
        if (!context->running_data.b->auth_evin.evin_req_secc_ok)
        {
            LOG_WARNING("[%d]evin_req_secc_ok", context->tag);
            context->running_data.b->auth_evin.evin_req_secc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_AUTH_EVIN_RESULT_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_auth_evin_result_secc(context->tag
            , &context->running_data.b->auth_evin.evin_result_secc
            , &msg.msg.auth_evin_result_secc
        );
        if (!context->running_data.b->auth_evin.evin_result_secc_ok)
        {
            LOG_WARNING("[%d]evin_result_secc_ok", context->tag);
            context->running_data.b->auth_evin.evin_result_secc_ok = 1;
            changed = true;
        }
        break;
#endif
#endif
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_RESERVE == CONFIG_YES)
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_RESERVE_EVCC == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_RESERVE_INFO_SECC:
        // changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_reserve_info_secc(context->tag
        //     , &context->running_data.b->reserve.reserve_info_secc
        //     , &msg.msg.reserve_info_secc
        // );
        // if (!context->running_data.b->reserve.reserve_info_secc_ok)
        // {
        //     LOG_WARNING("[%d]reserve_info_secc_ok", context->tag);
        //     context->running_data.b->auth_evin.reserve_info_secc_ok = 1;
        //     changed = true;
        // }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_RESERVE_CONFIRM_SECC:
        // changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_reserve_confirm_secc(context->tag
        //     , &context->running_data.b->reserve.reserve_confirm_secc
        //     , &msg.msg.reserve_confirm_secc
        // );
        // if (!context->running_data.b->reserve.reserve_confirm_secc_ok)
        // {
        //     LOG_WARNING("[%d]reserve_confirm_secc_ok", context->tag);
        //     context->running_data.b->auth_evin.reserve_confirm_secc_ok = 1;
        //     changed = true;
        // }
        break;
#endif
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SELFCHECK == CONFIG_YES)
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SELFCHECK_GENERAL == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_SELFCHECK_STATUS_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_selfcheck_status_secc(context->tag
            , &context->running_data.b->self_check.selfcheck_status_secc
            , &msg.msg.selfcheck_status_secc
        );
        if (!context->running_data.b->self_check.selfcheck_status_secc_ok)
        {
            LOG_WARNING("[%d]selfcheck_status_secc_ok", context->tag);
            context->running_data.b->self_check.selfcheck_status_secc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_SELFCHECK_RESULT_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_selfcheck_result_secc(context->tag
            , &context->running_data.b->self_check.selfcheck_result_secc
            , &msg.msg.selfcheck_result_secc
        );
        if (!context->running_data.b->self_check.selfcheck_result_secc_ok)
        {
            LOG_WARNING("[%d]selfcheck_result_secc_ok", context->tag);
            context->running_data.b->self_check.selfcheck_result_secc_ok = 1;
            changed = true;
        }
        break;
#endif
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_SUPPLY == CONFIG_YES)
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_SUPPLY_BASIC == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_SUPPLY_STATUS_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_supply_status_secc(context->tag
            , &context->running_data.b->supply.supply_status_secc
            , &msg.msg.supply_status_secc
        );
        if (!context->running_data.b->supply.supply_status_secc_ok)
        {
            LOG_WARNING("[%d]supply_status_secc_ok", context->tag);
            context->running_data.b->supply.supply_status_secc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_SUPPLY_ABILITY_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_supply_ability_secc(context->tag
            , &context->running_data.b->supply.supply_ability_secc
            , &msg.msg.supply_ability_secc
        );
        if (!context->running_data.b->supply.supply_ability_secc_ok)
        {
            LOG_WARNING("[%d]supply_ability_secc_ok", context->tag);
            context->running_data.b->supply.supply_ability_secc_ok = 1;
            changed = true;
        }
        break;
#endif
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_CHARGING == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_READY_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_charging_ready_secc(context->tag
            , &context->running_data.b->charging.charging_ready_secc
            , &msg.msg.charging_ready_secc
        );
        if (!context->running_data.b->charging.charging_ready_secc_ok)
        {
            LOG_WARNING("[%d]charging_ready_secc_ok", context->tag);
            context->running_data.b->charging.charging_ready_secc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_ABILITY_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_charging_ability_secc(context->tag
            , &context->running_data.b->charging.charging_ability_secc
            , &msg.msg.charging_ability_secc
        );
        if (!context->running_data.b->charging.charging_ability_secc_ok)
        {
            LOG_WARNING("[%d]charging_ability_secc_ok", context->tag);
            context->running_data.b->charging.charging_ability_secc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_CHARGING_PAUSE_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_charging_pause_secc(context->tag
            , &context->running_data.b->charging.charging_pause_secc
            , &msg.msg.charging_pause_secc
        );
        if (!context->running_data.b->charging.charging_pause_secc_ok)
        {
            LOG_WARNING("[%d]charging_pause_secc_ok", context->tag);
            context->running_data.b->charging.charging_pause_secc_ok = 1;
            changed = true;
        }
        break;
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_DISCHARGING == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_READY_EVCC:

        break;
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_REQUIREMENT_EVCC:

        break;
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_STATUS_EVCC:

        break;
    case OPENCHAOJI_GBT27930_B_PGI_DISCHARGING_INFO_BASIC_EVCC:

        break;
#endif

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FUNC_STATISTICS == CONFIG_YES)
#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B_FDC_STATISTICS == CONFIG_YES)
    case OPENCHAOJI_GBT27930_B_PGI_STATISTICS_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_statistics_secc(context->tag
            , &context->running_data.b->statistics.statistics_secc
            , &msg.msg.statistics_secc
        );
        if (!context->running_data.b->statistics.statistics_secc_ok)
        {
            LOG_WARNING("[%d]statistics_secc_ok", context->tag);
            context->running_data.b->statistics.statistics_secc_ok = 1;
            changed = true;
        }
        break;
#endif
#endif

    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_PHASE_INFO_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_phase_info_secc(context->tag
            , &context->running_data.b->phase_info_secc
            , &msg.msg.phase_info_secc
        );
        if (!context->running_data.b->phase_info_secc_ok)
        {
            LOG_WARNING("[%d]phase_info_secc_ok", context->tag);
            context->running_data.b->phase_info_secc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_STOP_INFO_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_stop_info_secc(context->tag
            , &context->running_data.b->stop_info_secc
            , &msg.msg.stop_info_secc
        );
        if (!context->running_data.b->stop_info_secc_ok)
        {
            LOG_WARNING("[%d]stop_info_secc_ok", context->tag);
            context->running_data.b->stop_info_secc_ok = 1;
            changed = true;
        }
        break;
    case OPENCHAOJI_GBT27930_B_PGI_PUBLIC_RELAY_STATUS_SECC:
        changed = OpenChaoJi_gbt27930_b_msg_cmpcpy_relay_status_secc(context->tag
            , &context->running_data.b->relay_status_secc
            , &msg.msg.relay_status_secc
        );
        if (!context->running_data.b->relay_status_secc_ok)
        {
            LOG_WARNING("[%d]relay_status_secc_ok", context->tag);
            context->running_data.b->relay_status_secc_ok = 1;
            changed = true;
        }
        break;
    default:
        LOG_ERR("[%d]Unknown PID[%02X]", context->tag, recv_data->recv_data.data[0]);
        goto PARSE_FAILED;
    }

    // 接收数据发生变化必须打出完整报文, 打印级别是INFO则把所有报文打印出来
    if ((changed) || ((OpenChaoJi_debug_get_log_level() & DBGL_INFO) != 0))
    {
        if ((msg.pid == OPENCHAOJI_GBT27930_B_PGI_PUBLIC_RELAY_STATUS_SECC)
        )
        {
            if (!changed && !s_gbt_b_public_debug_enable)
            {
                return 0;
            }
        }

        OpenChaoJi_gbt27930_b_msg_log(&msg);
        if ((OpenChaoJi_debug_get_log_level() & DBGL_INFO) != 0)
        {
            LOG_DATA_NORMAL("<-[%02X][%d]", msg.pid, recv_data->recv_data.len);
            LOG_DATA_BUFF_NORMAL(recv_data->recv_data.data, recv_data->recv_data.len);
        }
    }

	return 0;

PARSE_FAILED:
    LOG_ERR("[%d]Invalid MsgFromSecc", context->tag);
    LOG_BUFF_ERR(recv_data->recv_data.data, recv_data->recv_data.len);
    return -1;
}

#endif
